2011-11-11 15 views
5

Tôi đang sử dụng jQuery và tôi có một yêu cầu AJAX không đồng bộ. Tôi biết tôi có thể chờ đợi cho tất cả chúng được hoàn thành bằng cách sử dụng phương thức '$ .when.apply (array_of_requests)'().Làm thế nào để đợi cho đến khi các yêu cầu jQuery AJAX lồng nhau không đồng bộ đã kết thúc?

Nhưng tôi cũng có một bộ yêu cầu AJAX khác chỉ được thực hiện sau khi mỗi yêu cầu đầu tiên được hoàn tất. Tôi cũng muốn đợi họ hoàn thành, nhưng tôi không chắc chắn 100% là tôi đã tìm ra cách tốt nhất.

Dưới đây là một ví dụ đơn giản yêu cầu của tôi:

var intital_data = [1,2,3,4,5,6,7,8,9,10]; 
var promises = []; 
var promises_inner = []; 

$.each(intitial_data, function(i, n) { 
    var ajax_call = $.ajax({url:'http://www.domain.com/etc/'+n}); 
    promises.push(ajax_call); 

    ajax_call.done(function(data) { 
     var ajax_call_inner = $.ajax({url:'http://www.domain.com/etc/'+data.result}); 
     promises_inner.push(ajax_call_inner); 

     ajax_call_inner.done(function(data) { 
      // Do something with the content of data here. 
     }); 
    }); 
}); 

Vì vậy, khi mỗi người trong số mười looped yêu cầu AJAX được thực hiện, tôi thực hiện một yêu cầu AJAX thứ hai dựa trên kết quả đầu tiên. Tất cả đều hoạt động tốt.

sau đó tôi có một cái gì đó như thế này, bởi vì tôi muốn đợi cho đến khi cả mười yêu cầu đầu tiên (được lưu trữ trong mảng hứa hẹn) lô thứ hai (được lưu trữ trong promises_inner) được hoàn thành:

$.when.apply($, promises).then(
    function() { 
     // The ten outer AJAX calls are finished now. 

     $.when.apply($, promises_inner).then(
      function() { 
       // The inner AJAX calls are finished now. 
      } 
     ); 
    } 
); 

Trong hàm $ đầu tiên .when.apply(). Sau đó() 'được thực hiện', yêu cầu thứ hai chưa được hoàn thành, hoặc thậm chí được thêm vào mảng promise_inner. Nhưng tôi thấy rằng thêm một lồng nhau $ .when.apply(). Sau đó() dường như làm việc - trong chức năng 'thực hiện' của nó tất cả các yêu cầu đã hoàn thành.

Nhưng tôi không chắc đây là giải pháp tốt nhất và mạnh mẽ nhất. Tôi lo lắng rằng nó chỉ hoạt động trùng hợp - rằng nó gây ra sự chậm trễ vừa đủ cho các cuộc gọi đã hoàn thành - thay vì có ý nghĩa logic.

Có giải pháp tốt hơn, vững chắc hơn không? Cảm ơn.

+0

tôi đã nói chuyện quá sớm khi tôi nói rằng có vẻ như để làm việc. Đôi khi nó hoạt động, nhưng đôi khi, promises_inner đã không có tất cả các quảng cáo truy vấn AJAX lồng nhau suy luận về nó. Vì vậy, đôi khi bên trong $ .when xảy ra trước khi tất cả mọi thứ đã được trả lại. –

Trả lời

2

Hãy xem $ .Callbacks in 1.7. Tôi nghĩ bạn sẽ vui mừng về tính linh hoạt của việc tạo ra "dòng chảy" của riêng bạn và khả năng tái sử dụng chúng, chạy một lần, v.v.

Không có gì sai với những gì bạn đã làm (mẫu áp dụng có thể không phải là lựa chọn đầu tiên của hầu hết, họ thường chỉ cần liệt kê chúng trong một $ .when (a, b, c ....) - nhưng bạn có thể thích cú pháp $ .Callbacks tốt hơn.

+0

Cảm ơn con trỏ. Các tài liệu $ .Callbacks đang làm cho bộ não của tôi bị tổn thương nhưng tôi hy vọng nó sẽ chìm trong cuối cùng! Trong khi chờ đợi, bạn có nghĩ rằng giá trị lồng nhau của tôi là $ .when ... s có đáng tin cậy không? –

+0

Chúng ta phải làm những việc tương tự khi xử lý các quy tắc trong ứng dụng bảo hiểm của chúng tôi vì có ít nhất 10 dịch vụ liên quan. Một thứ khác bạn có thể làm mà có thể dễ đọc hơn là tạo ra một Trì hoãn và chỉ giải quyết nó khi lần đầu tiên khi hoàn thành. Sử dụng lời hứa của Deferred đó là .done cho tập hợp các callback tiếp theo. Addy Osmani có một bài viết hay về Callbacks và nhiều khả năng sẽ đến. – AutoSponge

0

Hãy thử điều này chỉ với một lời hứa chính fullfill (quyết tâm) mỗi vòng chạy (ở đây vẫn gọi là inner_promise).

var initial_data = [1,2,3,4,5,6,7,8,9,10]; 
var promises_inner = []; 

initial_data.forEach(function(n) { 
    // Create promise for the inner call here. 
    var promise_inner = $.Deferred(); 
    promises_inner.push(promise_inner); 

    $.ajax({url:'http://www.domain.com/etc/'+n}).done(function(data) { 
     $.ajax({url:'http://www.domain.com/etc/'+data.result}).done(function(data) { 
      // Do something with the content of data here. 
      promise_inner.resolve(); 
     }); 
    }); 
}); 
console.log("promises_inner contains " + promises_inner.length + " promises") // should contain all the 10 promises 

$.when.apply($,promises_inner).done(function() { 
    // The inner AJAX calls are finished now 
}) 
Các vấn đề liên quan