2015-09-14 42 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”会立即拒绝。我已经更新了答案,将其标记出来,如果你想继续等待所有人,即使其中一人失败了,也要给出一个替代方案。 –

相关问题