2013-02-26 32 views
10

Tôi đang tìm kiếm một cách để làm một gọi lại sau khi hai cuộc gọi ajax hoàn thành:jquery hoãn - đợi đến hai cuộc gọi hoàn

$.when(
    call1(), 
    call2() 
).always(function() { 
    // Here I want to be sure the two calls are done and to get their responses 
); 

Việc nắm bắt được rằng một trong những cuộc gọi có thể thất bại. Vì vậy, trong mã của tôi, luôn luôn sẽ được gọi mà không phải chờ cuộc gọi khác.

Làm cách nào để đợi cả hai cuộc gọi được thực hiện (thành công hay thất bại)?

+1

Bạn có thể muốn xem xét các lời hứa http://api.jquery.com/promise/ – BlueBird

+0

@BlueBird: Làm cách nào? lời hứa yêu cầu đối tượng jquery mà tôi không có. Bạn có thể thêm một ví dụ? – Naor

+1

@BlueBird: '$ .when' đã trả về đối tượng lời hứa, tức là OP đã sử dụng lời hứa. –

Trả lời

11

Đây là cái gì đó nên làm các trick:

$.whenAllDone = function() { 
    var deferreds = []; 
    var result = $.Deferred(); 

    $.each(arguments, function(i, current) { 
     var currentDeferred = $.Deferred(); 
     current.then(function() { 
      currentDeferred.resolve(false, arguments); 
     }, function() { 
      currentDeferred.resolve(true, arguments); 
     }); 
     deferreds.push(currentDeferred); 
    }); 

    $.when.apply($, deferreds).then(function() { 
     var failures = []; 
     var successes = []; 

     $.each(arguments, function(i, args) { 
      // If we resolved with `true` as the first parameter 
      // we have a failure, a success otherwise 
      var target = args[0] ? failures : successes; 
      var data = args[1]; 
      // Push either all arguments or the only one 
      target.push(data.length === 1 ? data[0] : args); 
     }); 

     if(failures.length) { 
      return result.reject.apply(result, failures); 
     } 

     return result.resolve.apply(result, successes); 
    }); 

    return result; 
} 

Check-out this Fiddle để xem cách nó hoạt động.

Về cơ bản, nó chờ tất cả Trì hoãn hoàn thành bất kể chúng có bị lỗi hay không và thu thập tất cả các kết quả. Nếu chúng ta có thất bại, sự trì hoãn được trả về sẽ thất bại với một danh sách tất cả các thất bại và giải quyết với tất cả những thành công khác.

+0

Cảm ơn. Tôi đã hy vọng jquery đã có giải pháp cho việc này. – Naor

+0

Không. Tôi nghĩ rằng trường hợp phổ biến hơn là bạn không cần phải chờ tất cả hoãn lại để kết thúc nếu có bất kỳ lỗi nào trong số đó bị lỗi. – Daff

+0

Vì vậy, nó là chính xác để giả định rằng thứ tự của các đối số succes là giống như thứ tự của các trì hoãn thêm? đối số [0] từ dfd1? – DavidVdd

1

Nó không phải là đẹp, nhưng bạn có thể có một biến "hoàn thành" toàn cầu cho mỗi cuộc gọi ajax để thiết lập khi hoàn thành. Mỗi cuộc gọi cũng sẽ kiểm tra xem cả hai biến đã được đặt hay chưa và nếu có, hãy gọi hàm luôn luôn của bạn.

0

Bạn cũng có thể tổ các cuộc gọi:

$.when(call1()).always(function(){ 
    $.when(call2()).always(function(){ 
     // Here I want to be sure the two calls are done and to get their responses 
    }); 
}); 

Nhưng tất nhiên hai cuộc gọi sẽ trở thành đồng bộ với nhau.

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