在jQuery中使用foreach语句完成所有ajax请求后调用函数

Sna*_*yes 5 ajax jquery

我有一个each声明,在其中我调用ajax向服务器发送一些信息.

$.each(array, function(k, v) {
   $.ajax({
       ...
   });
});
Run Code Online (Sandbox Code Playgroud)

所有的 ajax请求完成后,在这里调用一个函数......怎么做?

我不能再使用async: falseflag了,因为它已被弃用.

T.J*_*der 13

存储$.ajax数组中返回的promise ,然后使用$.when等待它们全部完成:

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

或使用$.map:

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

你会想看看done,thenalways以确定哪些是最适合您的方案.

$.when的API是有点碎设计略有不同的使用情况,这就是为什么我们要调用它在奇怪的方式.它的作用是接受一堆promises作为离散参数,并返回一个新的promise,当你传递的所有promise都被解析时,它将被解析.例如:

$.when(promise1, promise2, promise3).then(...);
Run Code Online (Sandbox Code Playgroud)

但是我们经常会有一系列的承诺(如上所述).由于它需要离散参数,我们用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();
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

只是等待它们全部,然后根据它们中的任何一个是否失败来解决或拒绝.你可以进一步,解决或拒绝一系列结果.


$.when通过为自己提供实用功能,您可以使用数组更方便:

function whenAll(array) {
    return $.when.apply($, array);
}
Run Code Online (Sandbox Code Playgroud)

...然后:

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

你甚至可以添加它$,但当然,jQuery的未来版本可能会定义whenAll,所以要谨慎.