当前位置: 首页 > 知识库问答 >
问题:

我如何等待一组异步回调函数?

仉嘉泽
2023-03-14

我的JavaScript代码如下所示:

forloop {
    //async call, returns an array to its callback
}

完成所有这些异步调用后,我想计算所有数组的最小值。

我怎么能等到他们所有人呢?

我现在唯一的想法是有一个布尔数组叫做done,并在第i个回调函数中将done[i]设置为true,然后说while(not all are done){}

edit:我想一个可能的,但很难看的解决方案是在每个回调中编辑done数组,然后在每个回调中设置了所有其他done的情况下调用一个方法,这样最后一个要完成的回调将调用continuing方法。

提前道谢。

共有1个答案

涂浩皛
2023-03-14

您的代码不是很具体,所以我将编一个场景。假设您有10个ajax调用,您想要累积这10个ajax调用的结果,然后当它们全部完成时,您想要做一些事情。您可以这样做,方法是将数据累加到数组中,并跟踪最后一个数据完成的时间:

手动计数器

var ajaxCallsRemaining = 10;
var returnedData = [];

for (var i = 0; i < 10; i++) {
    doAjax(whatever, function(response) {
        // success handler from the ajax call

        // save response
        returnedData.push(response);

        // see if we're done with the last ajax call
        --ajaxCallsRemaining;
        if (ajaxCallsRemaining <= 0) {
            // all data is here now
            // look through the returnedData and do whatever processing 
            // you want on it right here
        }
    });
}

注意:错误处理在这里很重要(没有显示,因为它特定于如何进行ajax调用)。您需要考虑如何处理当一个ajax调用从未完成时的情况,或者出现错误,或者长时间卡住,或者长时间后超时。

补充了我2014年的回答。现在,promise经常被用来解决这类问题,因为jQuery的$.ajax()已经返回了一个promise,而$.when()会让您知道一组promise何时全部解决,并为您收集返回结果:

var promises = [];
for (var i = 0; i < 10; i++) {
    promises.push($.ajax(...));
}
$.when.apply($, promises).then(function() {
    // returned data is in arguments[0][0], arguments[1][0], ... arguments[9][0]
    // you can process it here
}, function() {
    // error occurred
});

ES6标准promise

正如KBA的回答中所指定的:如果您有一个内置本机promise的环境(modern browser或Node.js或使用babeljs transpile或使用一个promisepolyfill),那么您可以使用ES6指定的promise。有关浏览器支持,请参阅下表。除了IE之外,几乎所有当前的浏览器都支持promise。

如果doajax()返回一个promise,那么您可以这样做:

var promises = [];
for (var i = 0; i < 10; i++) {
    promises.push(doAjax(...));
}
Promise.all(promises).then(function() {
    // returned data is in arguments[0], arguments[1], ... arguments[n]
    // you can process it here
}, function(err) {
    // error occurred
});

如果您需要将一个非promise异步操作转换为返回promise的异步操作,您可以像这样“promise”它:

function doAjax(...) {
    return new Promise(function(resolve, reject) {
        someAsyncOperation(..., function(err, result) {
            if (err) return reject(err);
            resolve(result);
        });
    });
}

然后使用上面的模式:

var promises = [];
for (var i = 0; i < 10; i++) {
    promises.push(doAjax(...));
}
Promise.all(promises).then(function() {
    // returned data is in arguments[0], arguments[1], ... arguments[n]
    // you can process it here
}, function(err) {
    // error occurred
});

如果您使用一个功能更丰富的库,比如Bluebird promise库,那么它还内置了一些额外的功能,使其更容易实现:

 var doAjax = Promise.promisify(someAsync);
 var someData = [...]
 Promise.map(someData, doAjax).then(function(results) {
     // all ajax results here
 }, function(err) {
     // some error here
 });
 类似资料:
  • 问题内容: 我的代码在javascript中看起来像这样: 在完成所有这些异步调用之后,我想计算所有数组的最小值。 我要如何等待所有人? 我现在唯一的想法是拥有一个名为done的布尔数组,并在第i个回调函数中将done [i]设置为true,然后说while(不是全部都完成了){} 编辑:我想一个可能但很丑陋的解决方案是在每个回调中编辑完了的数组,然后如果每个回调中都设置了所有其他完成,则调用一个

  • 本文向大家介绍承诺回调和异步/等待,包括了承诺回调和异步/等待的使用技巧和注意事项,需要的朋友参考一下 首先,我们必须了解两个主要概念 同步编程 异步编程 同步编程 它等待每个语句完成执行,然后再转到下一条语句。 如果语句不相互依赖,但是由于它们在队列中,它们仍在等待执行,则此方法可能会减慢应用程序的速度。 异步编程 在移动到下一条语句之前,它不等待当前语句完成执行。例如,调用Web服务并使用Ja

  • 问题内容: 我知道这个问题以前曾被问过,但是所有解决方案都不适合我。 我有一个将参数发送到API的函数,并以列表的形式返回数据。我有一个UITableView设置为使用该列表,但是它在列表分配给变量之前运行。 码: 如果不立即将其作为重复投票,我将不胜感激,这是我尝试的方法。 派遣组 信号量计时 运行变量 其中包括= self和= self 。 编辑:要求提取项目, 问题答案: 您不能-也不应该-

  • 我想返回用户的电话号码,但我得到的是[对象对象]。我在想,如果它在等待完成之前返回值。这是我的代码。 输出12345678,以便我可以在异步函数外部访问它。例如,要在个人资料页面中显示它,

  • 我正试图将图像上传到firebase存储,但调用该函数时,未执行wait以获取url。我错过了什么? 看看这个其他主题,我发现问题可能是“然后”,但我如何设置代码以等待url? 异步/等待/然后飞镖/颤振 谢谢

  • 问题内容: 我正在使用fast-csv使用来遍历CSV文件。对于CSV文件的每一行,我想在redis中创建一个作业,为此我使用kue。解析行是同步功能。整个过程看起来像这样: CSV文件每一行的简单显示,但是未创建作业。即,没有打印出回调中的输出,并且该作业不在我的Redis中。 我假设,因为它是CSV文件的最后一行,所以该流已经发出,因此最后一个不能在进程终止之前执行吗? 有没有办法在完成kue