2009-09-20 13 views
6

Tôi đang viết một plugin phổ biến chức năng gọi lại chức năng dài cho truy vấn ajax đang chặn Chủ đề GUI khiến cho Firefox bị khóa.Có cách nào chính xác để 'mang lại' trong ý nghĩa luồng hợp tác trong javascript không?

Giải pháp rõ ràng có vẻ là sử dụng một số loại thực hiện hoãn lại (nghĩa là chúng tôi muốn định kỳ thêm thực hiện truy vấn này chức năng vào cuối hàng đợi sự kiện và sau đó cho phép các lệnh khác được thực hiện .

cách duy nhất tôi có thể nghĩ để làm điều này là sử dụng setTimeout với một thời gian chờ của zero ... được này được đảm bảo để làm việc, hoặc là có một cách tốt hơn để làm điều này.

+0

Bạn đang làm AJAX như thế nào? Nếu bạn đang tải một thẻ tập lệnh, điều đó có thể bị chặn (khối trình duyệt cho đến khi tập lệnh trở lại). –

+0

Tôi đang sử dụng jQuery.get – user47741

Trả lời

7

sử dụng setTimeout với một thời gian chờ rất nhỏ (0 hoặc rất gần bằng không nếu bạn cảm thấy hoang tưởng) là cách duy nhất để thực hiện điều này trong ngữ cảnh trình duyệt. hoạt động rất tốt và rất đáng tin cậy, nhưng hãy chắc chắn mang lại đủ thường xuyên nhưng không phải quá thường xuyên, vì phải mất một thời gian để quay lại với bạn ("một lúc" trong ý nghĩa máy tính, tất nhiên; nó gần như tức thời [modulo những thứ khác bạn có thể làm] về mặt con người).

+2

Tất cả các triển khai trình duyệt hiện đại đều đã cài đặt setTimeout thành ~ 10ms (về cơ bản là 10ms trên tất cả các hệ thống không cửa sổ, ở đó độ phân giải bộ hẹn giờ cần có thời gian <16ms có tác động đáng kể đến mức sử dụng năng lượng). Vì vậy, bạn không thực sự cần phải lo lắng về việc thiếu thời gian chờ. – olliej

+1

@olliej: Đó là thông tin lỗi thời (nếu nó đã đúng trong năm09, nhưng cũng không phải là trải nghiệm của tôi). Các trình duyệt xử lý phức tạp hơn nhiều, tùy thuộc vào nguồn gốc của lệnh gọi 'setTimeout'. Điều này đã được [mã hóa một vài năm trước trong thông số HTML5] (http://www.w3.org/TR/html5/webappapis.html#timer-initialization-steps) nhưng như tôi đã nói, các nhà cung cấp đã chơi (khác nhau) trò chơi trước đó. Phiên bản ngắn: Nếu mã của bạn không được gọi bởi bộ hẹn giờ, bạn có thể sử dụng 0 và các trình duyệt hiện đại sẽ nhận được ** rất ** gần đó. –

3

Đảm bảo bạn đang sử dụng yêu cầu không đồng bộ vì yêu cầu đồng bộ chặn trình duyệt (điều này sẽ giải thích việc khóa GUI).

Nếu đây không phải là vấn đề của bạn, tôi nghĩ bạn muốn một thứ như hàng đợi nhiệm vụ này.

var queue = []; 

queue.push(someTaskFunction); 
queue.push(anotherTaskFunction); 
// ... 

var runQueue = (function() { 
    var len = queue.length, task = 0; 
    for (; task < len; task++) { 
     yield queue[task](); 
    } 
}()); 

Gọi runQueue.next() để thực hiện tác vụ tiếp theo. Quấn nó vào một câu lệnh try..catch như vậy:

try { 
    runQueue.next(); 
} catch (e if (e instanceof StopIteration)) {} 
+0

Cuộc gọi là vô ích – user47741

+0

Tuyệt vời - Tôi không biết rằng máy phát đã được thêm vào javascript. Tôi có đúng khi hiểu rằng các nhiệm vụ khác có thể kiểm soát bất cứ khi nào một hàm trả về sau đó? – user47741

+0

Lưu ý rằng các trình tạo mới tương đối mới đối với JavaScript và không nhất thiết phải được hỗ trợ rộng rãi. –

Các vấn đề liên quan