2011-11-11 64 views
5

我正在使用jQuery,並且有一個異步AJAX請求循環。我知道我可以通過使用方便的'$ .when.apply(array_of_requests).then()'方法等待它們全部完成。如何等待,直到嵌套異步jQuery AJAX請求已完成?

但我也有另一套AJAX請求,只在每個第一個請求完成後才執行。我想等他們完成,但我不是100%確定我找到了最好的方法。

這裏是我的請求,一個簡單的例子:

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. 
     }); 
    }); 
}); 

所以,當每個十環AJAX請求完成後,我做基於第一結果的第二AJAX請求。這一切都很好。

我再有這樣的事情,因爲我要等到雙方的前十個請求(存儲的承諾陣列)第二批(存儲在promises_inner)完成:

$.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. 
      } 
     ); 
    } 
); 

在第一個$ .when.apply()。then()的'done'函數中,第二批請求還沒有完成,甚至還沒有添加到promises_inner數組中。但我發現添加一個嵌套的$ .when.apply()。then()似乎工作 - 在其「完成」功能全部請求已完成。

但我不確定這是最好的,最健壯的解決方案。我擔心它只能在巧合的情況下工作 - 它只會導致電話完成的延遲 - 而不是合乎邏輯的意義。

有更好的,更堅固的解決方案嗎?謝謝。

+0

我很快就談到過,當我說,它似乎工作。有時,它的工作原理,但其他時候,promises_inner一直沒有所有的嵌套的AJAX查詢廣告還沒有。所以有時候內部的$ .when發生在所有的東西都被返回之前。 –

回答

2

看看1.7中的$ .Callbacks。我認爲你會對製作自己的「流量」的靈活性以及重用它們的能力感到興奮,只需運行一次等等。

你做了什麼沒有問題(應用模式可能不是第一選擇大多數情況下,他們通常只是在$ .when(a,b,c ....)中列出它們 - 但是您可能更喜歡$ .Callbacks的語法。

+0

感謝您的指針。 $ .Callbacks文檔讓我的大腦受到傷害,但我希望它最終會沉入其中!與此同時,你認爲我的嵌套$ .when應該是可靠的嗎? –

+0

在我們的保險應用程序中處理規則時,我們必須做類似的事情,因爲至少涉及10個服務。你可以做的更容易閱讀的另一件事是創建一個Deferred,並且只在第一個完成時解析它。將Deferred的承諾用作下一組回調的.done。 Addy Osmani在回調方面有很好的文章,可能還會有更多。 – AutoSponge

0

試試這個只有一個主要承諾fullfill(解析)每個循環運行(這裏仍稱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 
})