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

时间:2022-08-23 19:34:30

I have an each statement and inside it I call ajax to send some information to server.

我有一个语句,在它里面我调用ajax向服务器发送一些信息。

$.each(array, function(k, v) {
   $.ajax({
       ...
   });
});

When all ajax requests are done then call a function here... How to do that ?

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

I cannot use async: false flag anymore because it is deprecated.

我不能再使用async: false标志,因为它已经被弃用了。

1 个解决方案

#1


12  

Store the promises returned by $.ajax in an array, and then use $.when to wait for them all to complete:

存储$ $返回的承诺。在数组中使用ajax,然后使用$。何时等待它们全部完成:

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

or using $.map:

或者使用$ . map:

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

You'll want to look at done, then, and always to determine which is best for your scenario.

然后,您将希望查看done,并始终确定哪个是最适合您的场景的。

$.when's API is a bit broken designed for a slightly different use case, which is why we have to call it in that odd way. What it does is accept a bunch of promises as discrete arguments, and return a new promise that will be resolved when all of the promises you pass it are resolved. E.g.:

美元。when的API是为一个稍微不同的用例而设计的,这就是为什么我们必须以这种奇怪的方式调用它。它所做的是接受一系列的承诺作为离散的论点,并返回一个新的承诺,当你通过的所有承诺都得到解决时,这个承诺将被解决。例如:

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

But frequently we have an array of promises (such as in the above). Since it expects discrete arguments, we use Function#apply to call it, since Function#apply accepts an array and then calls the function with the entries from the array as discrete arguments.

但是我们经常有一系列的承诺(如上面所示)。因为它需要离散的参数,所以我们使用函数#来调用它,因为函数#apply接受一个数组,然后用数组中的条目作为离散参数调用函数。

Note: $.when resolves the promise it returns when all of the promises you give it are resolved, or rejects its promise when any of the promises you give it is rejected. So if one of the ajax calls fails, you'll get your callback right away, even if other calls are still outstanding.

注意:美元。当解决承诺时,当你做出的所有承诺都得到解决,或者当你做出的任何承诺都被拒绝时,它就会返回。因此,如果其中一个ajax调用失败了,即使其他调用仍然很出色,您也可以立即得到回调。

If you don't want that, then you have to write your own function, which isn't hard; something a bit like this:

如果你不想这样,那你就得写你自己的函数,这不难;有点像这样:

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

That just waits for them all, and then either resolves or rejects depending on whether any of them failed. You could take it further, resolving or rejecting with an array of results.

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


You can make $.when with an array a bit more convenient by giving yourself a utility function:

你可以让美元。当数组更方便的时候给自己一个实用函数:

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

...and then:

…然后:

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

You could even add that to $, but of course, a future version of jQuery may define whenAll, so be cautious.

您甚至可以将其添加到$,但是当然,未来的jQuery版本可能会定义whenAll,所以要小心。

#1


12  

Store the promises returned by $.ajax in an array, and then use $.when to wait for them all to complete:

存储$ $返回的承诺。在数组中使用ajax,然后使用$。何时等待它们全部完成:

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

or using $.map:

或者使用$ . map:

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

You'll want to look at done, then, and always to determine which is best for your scenario.

然后,您将希望查看done,并始终确定哪个是最适合您的场景的。

$.when's API is a bit broken designed for a slightly different use case, which is why we have to call it in that odd way. What it does is accept a bunch of promises as discrete arguments, and return a new promise that will be resolved when all of the promises you pass it are resolved. E.g.:

美元。when的API是为一个稍微不同的用例而设计的,这就是为什么我们必须以这种奇怪的方式调用它。它所做的是接受一系列的承诺作为离散的论点,并返回一个新的承诺,当你通过的所有承诺都得到解决时,这个承诺将被解决。例如:

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

But frequently we have an array of promises (such as in the above). Since it expects discrete arguments, we use Function#apply to call it, since Function#apply accepts an array and then calls the function with the entries from the array as discrete arguments.

但是我们经常有一系列的承诺(如上面所示)。因为它需要离散的参数,所以我们使用函数#来调用它,因为函数#apply接受一个数组,然后用数组中的条目作为离散参数调用函数。

Note: $.when resolves the promise it returns when all of the promises you give it are resolved, or rejects its promise when any of the promises you give it is rejected. So if one of the ajax calls fails, you'll get your callback right away, even if other calls are still outstanding.

注意:美元。当解决承诺时,当你做出的所有承诺都得到解决,或者当你做出的任何承诺都被拒绝时,它就会返回。因此,如果其中一个ajax调用失败了,即使其他调用仍然很出色,您也可以立即得到回调。

If you don't want that, then you have to write your own function, which isn't hard; something a bit like this:

如果你不想这样,那你就得写你自己的函数,这不难;有点像这样:

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

That just waits for them all, and then either resolves or rejects depending on whether any of them failed. You could take it further, resolving or rejecting with an array of results.

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


You can make $.when with an array a bit more convenient by giving yourself a utility function:

你可以让美元。当数组更方便的时候给自己一个实用函数:

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

...and then:

…然后:

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

You could even add that to $, but of course, a future version of jQuery may define whenAll, so be cautious.

您甚至可以将其添加到$,但是当然,未来的jQuery版本可能会定义whenAll,所以要小心。