2011-06-30 30 views
47

Tôi có chuỗi cuộc gọi ajax chậm trễ ba lớp và lý tưởng là họ sẽ hứa hẹn tất cả các cách khi lớp sâu nhất kết thúc (làm cho tôi điều Khởi động. .. "chúng ta cần phải đi sâu hơn!").jQuery hoãn lại - chờ đợi nhiều yêu cầu AJAX hoàn thành

Vấn đề là tôi đang gửi nhiều yêu cầu ajax (có thể là hàng trăm) cùng một lúc và cần trì hoãn cho đến khi tất cả chúng được thực hiện. Tôi không thể dựa vào người cuối cùng được thực hiện cuối cùng.

function updateAllNotes() { 
    return $.Deferred(function(dfd_uan) { 
     getcount = 0; 
     getreturn = 0; 
     for (i = 0; i <= index.data.length - 1; i++) { 
      getcount++; 
      $.when(getNote(index.data[i].key)).done(function() { 
       // getNote is another deferred 
       getreturn++ 
      }); 
     }; 
     // need help here 
     // when getreturn == getcount, dfd_uan.resolve() 
    }).promise(); 
}; 
+1

http://stackoverflow.com/questions/3709597/wait-until -all-jquery-ajax-request-are-done/9350515 # 9350515 – Benjamin

Trả lời

95

Bạn có thể sử dụng .when().apply() với nhiều trì hoãn. Cực kỳ hữu ích:

function updateAllNotes() { 
    var getarray = [], 
     i, len; 

    for (i = 0, len = data.length; i < len; i += 1) { 
     getarray.push(getNote(data[i].key)); 
    }; 

    $.when.apply($, getarray).done(function() { 
     // do things that need to wait until ALL gets are done 
    }); 
} 
+8

Bạn cũng có thể _accept_ câu trả lời của riêng bạn. Bằng cách này, bạn có thể giúp những người khác đang phải đối mặt với một vấn đề tương tự, bởi vì họ sẽ thấy rằng vấn đề này đã được giải quyết trong kết quả tìm kiếm của họ. :) – Exa

+0

Cảm ơn. Được đánh dấu là đã chấp nhận – brittohalloran

+0

Có lý do nào để chỉ định '$' làm đối số đầu tiên áp dụng không? Tôi hiểu rằng đó là ngữ cảnh của cuộc gọi, nhưng không phải là bối cảnh bình thường cho một cuộc gọi jQuery 'window' hoặc thậm chí là' null'? – Ryley

5

Cảm ơn câu trả lời brittohalloran. Tôi cũng sử dụng dấu gạch dưới, vì vậy tôi đã có thể áp dụng giải pháp của bạn rất gọn gàng với bản đồ, giống như thế này:

$.when.apply($, _.map(data, function(i) { 
    return getNote(i.key); 
})).done(function() { 
    alert('Be Happy'); 
}); 

Wicked hữu ích.

25

Nếu bạn tham khảo jQuery.When doc, nếu một trong các cuộc gọi ajax của bạn không thành công, fail gọi lại chính sẽ được gọi ngay cả khi tất cả cuộc gọi ajax chưa kết thúc. Trong trường hợp này bạn không chắc chắn rằng tất cả các cuộc gọi của bạn đã hoàn tất.

Nếu bạn muốn chờ đợi cho tất cả các cuộc gọi của bạn, không có vấn đề gì kết quả là, bạn phải sử dụng một thu nhập hoãn lại như thế này:

$.when.apply($, $.map(data, function(i) { 
    var dfd = $.Deferred(); 
    // you can add .done and .fail if you want to keep track of each results individualy 
    getNote(i.key).always(function() { dfd.resolve(); }); 
    return dfd.promise(); 
}); 
+0

Tôi không nghĩ rằng luôn luôn giúp ở tất cả vì nó [vẫn chạy trước những lời hứa được hoàn thành] (http://jsfiddle.net/katowulf/J7H6M/). – Kato

+2

Có, nó giúp ích nếu bạn sử dụng cùng mã với tôi và gói lời hứa của bạn. [Tôi đã cập nhật fiddle của bạn] (http://jsfiddle.net/J7H6M/2/) với ví dụ của tôi, và nó hoạt động hoàn hảo. trong liên kết của bạn, bạn chỉ cần làm tương tự như brittohalloran, hai lời hứa không được bao bọc. Trong trường hợp này, nếu trường hợp đầu tiên không thành công, các cuộc gọi lại/không thành công sẽ được gọi ngay cả khi các lời hứa tiếp theo không kết thúc. – Mordhak

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