2015-09-14 117 views

回答

12

存儲由$.ajax在返回數組的承諾,然後用$.when等待他們全部完成:

var promises = []; 
$.each(array, function(k, v) { 
    promises.push($.ajax({ 
     ... 
    })); 
}); 
$.when.apply($, promises).then(function() { 
    // They're all done now 
}); 

或使用$.map

$.when.apply($, $.map(array, function(k, v) { 
    return $.ajax({ 
     ... 
    }); 
})).then(function() { 
    // They're all done now 
}); 

你想看看在done,thenalways,以確定哪個最適合您的方案。

$.when的API爲有點破壞設計用於略有不同的用例,這就是爲什麼我們必須以奇怪的方式調用它。它所做的是接受一系列承諾作爲離散的論點,並返回一個新的承諾,當你通過它的所有承諾都被解決時,這個承諾將被解決。例如: -

$.when(promise1, promise2, promise3).then(...); 

但是經常我們有承諾的陣列(如上述)。由於它需要離散參數,因此我們使用Function#apply來調用它,因爲Function#apply接受一個數組,然後使用數組中的條目作爲離散參數調用該函數。

注意$.when解決你給它的承諾得到解決它返回的承諾,或拒絕承諾時你給它拒絕承諾任何。因此,如果其中一個ajax呼叫失敗,您將立即得到回撥,即使其他呼叫尚未完成,也可以撥打

如果你不想那樣,那麼你必須編寫自己的函數,這並不難;有點像這樣:

function waitForAll(promises) { 
    var waitingFor = promises.length; 
    var allGood = true; 
    var oneResolved = oneSettled.bind(null, true); 
    var oneRejected = oneSettled.bind(null, false); 
    var d = $.Deferred(); 

    promises.forEach(function(promise) { 
     promise.then(oneResolved, oneRejected); 
    }); 

    return d.promise(); 

    function oneSettled(resolved) { 
     if (!resolved) { 
      allGood = false; 
     } 
     if (--waitingFor === 0) { 
      if (allGood) { 
       d.resolve(); 
      } else { 
       d.reject(); 
      } 
     } 
    } 
} 

只是等待他們所有,然後根據他們是否有任何失敗而解決或拒絕。你可以更進一步,解決或拒絕一系列結果。


您可以$.when與陣列通過給自己的效用函數有點更方便:

function whenAll(array) { 
    return $.when.apply($, array); 
} 

...然後:

whenAll($.map(array, function(k, v) { 
    return $.ajax({ 
     ... 
    }); 
})).then(function() { 
    // They're all done now 
}); 

你甚至可以添加到$,但當然,jQuery的未來版本可以定義whenAll,所以要特別小心。

+0

爲什麼不使用'done'而不是'then'? –

+0

@SnakeEyes:'then'提供多個函數可能是更好的選擇(如果你只提供一個函數,那麼'then'和'done'是相同的東西),或者'always'。即使有一個或多個ajax調用失敗,你可能也想要通知。 –

+0

@SnakeEyes:僅供參考,我只是注意到,當你給它的任何承諾被拒絕時,即使其他人仍然出色,「$ .when」會立即拒絕。我已經更新了答案,將其標記出來,如果你想繼續等待所有人,即使其中一人失敗了,也要給出一個替代方案。 –

相關問題