2012-01-24 25 views
5

Tôi có một cái gì đó như thế này:Làm thế nào để tôi biết khi nào async cuối cùng được thực hiện?

for (var i=0;i<result.qry.ROWCOUNT;i++) { 
    myAsync(i); 
} 

Làm thế nào để biết khi nào tất cả các chức năng async của tôi đã hoàn tất thi công?

Nguy cơ ai đó trả lời bằng "Cần thêm jQuery!", Tôi có thể sử dụng đối tượng lời hứa jQuery không? Hoặc trì hoãn hoặc một cái gì đó như thế?

+0

Với jQuery bạn có thể sử dụng '.done()' hoặc '.Sau đó()' kết hợp với '$ .Khi()': http : //stackoverflow.com/a/5817886/1095206 – BartekR

+0

Cảm ơn bạn rất nhiều. Đó là điều tôi đang tìm kiếm! –

Trả lời

1

Trong jQuery, có chức năng $.ajaxStop chạy sau khi Ajax cuối cùng đã chạy.

7

Theo dõi số lượng cuộc gọi không đồng bộ xuất sắc. Khi mỗi lần kết thúc, hãy giảm bộ đếm của bạn. Khi bạn đến 0, bạn đang ở trong cuộc gọi lại cuối cùng.

var asyncsLeft = 0; 
for (var i=0;i<10;++i){ 
    asyncsLeft++; 
    doSomethingAsyncWithCallback(function(){ 
    // This should be called when each asynchronous item is complete 
    if (--asyncsLeft==0){ 
     // This is the last one! 
    } 
    }); 
} 

Do tính chất đơn luồng JavaScript không có điều kiện chủng tộc tiềm năng nơi bạn có thể nhận cuộc gọi lại của bạn gọi trước khi tất cả các cuộc gọi không đồng bộ đã được xếp hàng. Bạn có thể thực hiện cuộc gọi asyncsLeft++ sau doSomethingAsynchronous nếu muốn.

+1

Tôi muốn đề xuất điều gì đó tương tự: sử dụng hai biến, một biến có tổng số tài nguyên và một biến theo dõi số lượng đã tải/không thành công (có thể trong hai biến khác). Với một biến, bạn có nguy cơ một cơ hội nhỏ mà một yêu cầu sẽ kết thúc trước khi mã tạo một cái mới, mà sẽ sớm cho rằng mọi thứ đã được nạp (có, điều này thực sự đã xảy ra với tôi). Ngoài ra, việc sử dụng hai biến có thể hiển thị tiến trình của tài nguyên đã tải. –

+0

@JeffreySweeney Nếu bạn đá tất cả chúng trong một vòng lặp, thì không, bạn không chạy rủi ro đó. Đó là những gì văn bản in nghiêng của tôi là về. Không có callbacks nào bắt đầu được gọi cho đến khi vòng lặp 'for' của bạn kết thúc. – Phrogz

-2

Sử dụng một hàm callback:

for (var i=0;i<result.qry.ROWCOUNT;i++) { 
    myAsync(i, myCallback); 
} 

function myCallback(i){ 
    //set result.qry.ROWCOUNT to a var somewhere above if it's not available in this scope 
    if(i == (result.qry.ROWCOUNT - 1)){ 
    //now you know you're actually done with all requests 
    } 
} 
function myAsync(i,callback){ 
    ///do work 
    callback(i); 
} 
+1

Điều này chỉ hoạt động nếu các tác vụ không đồng bộ hoàn thành theo thứ tự chúng được bắt đầu. –

+0

Trong trường hợp này, 'myAsync' là đồng bộ, bạn phải chuyển cuộc gọi lại đến bất kỳ phương thức/thư viện không đồng bộ nào bạn đang sử dụng. –

+0

điểm tuyệt vời –

1

Nếu bạn đang sử dụng jQuery, bạn cũng có thể sử dụng các phương pháp ajaxSendajaxComplete để giữ mã truy cập của bạn riêng biệt từ mã văn của bạn.

var ajaxPending = 0; 

function ajax_changed(indicator, pending) { 
    if (pending) 
     $(indicator).show(); 
    else 
     $(indicator).hide(); 
} 

$('#loading-indicator').ajaxSend(function() { 
    ajax_changed(this, ++ajaxPending); 
}); 

$('#loading-indicator').ajaxComplete(function() { 
    ajax_changed(this, --ajaxPending); 
}); 
2

Đây là cách tôi sẽ làm điều đó:

//Do stuff up here to get records 
var rowCount = result.qry.ROWCOUNT, //Save the row count 
    asyncCount = 0, //The count of complete async calls 
    asyncCallback = function() { 
     //To be called whenever an async operation finishes 
     asyncCount++; //Increment the row counter 
     if (asyncCount >= rowCount) { 
      //Do stuff when they're all finished 
     } 
    }; 

for (var i=0;i<rowCount;i++) { 
    myAsync(i, asyncCallback); 
} 

function myAsync(index, completeCallback) { 
    //Do async stuff with index 
    //Call completeCallback when async stuff has finished or pass it 
    // into the async function to be called 
} 
Các vấn đề liên quan