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

2024-03-11

我的代码在 javascript 中看起来像这样:

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

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

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

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

编辑:我想一个可能但丑陋的解决方案是在每个回调中编辑完成数组,然后如果每个回调设置了所有其他完成,则调用一个方法,因此最后一个完成的回调将调用继续方法。


你的代码不太具体,所以我会编一个场景。假设您有 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 调用永远无法完成时,您将如何处理这种情况,要么出现错误,要么卡住很长时间,或者很长时间后超时。


jQuery 的承诺

添加到我 2014 年的答案。自从 jQuery 出现以来,现在经常使用 Promise 来解决此类问题$.ajax()已经返回一个承诺并且$.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 标准承诺

正如 kba 的回答中所指定的 https://stackoverflow.com/a/33813793/576767:如果你有一个内置了原生 Promise 的环境(现代浏览器或 Node.js 或使用 babeljs Transpile 或使用 Promise Polyfill),那么你可以使用 ES6 指定的 Promise。看这张桌子 http://caniuse.com/#feat=promises用于浏览器支持。除了 IE 之外,当前几乎所有浏览器都支持 Promise。

If doAjax()返回一个承诺,那么你可以这样做:

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

如果您需要将非承诺异步操作变成返回承诺的异步操作,您可以像这样“承诺”它:

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

蓝鸟的承诺

如果您使用功能更丰富的库,例如蓝鸟承诺图书馆 http://bluebirdjs.com/docs/api-reference.html,然后它内置了一些附加函数以使这更容易:

 var doAjax = Promise.promisify(someAsync);
 var someData = [...]
 Promise.map(someData, doAjax).then(function(results) {
     // all ajax results here
 }, function(err) {
     // some error here
 });
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何等待一组异步回调函数? 的相关文章

随机推荐

  • 使用嵌入 API 谷歌分析设置 API 密钥

    我正在使用 embed api 用我的谷歌分析数据渲染地图 function w d s g js fs g w gapi w gapi g analytics q ready function f this q push f js d c
  • 如何在 Python 和 web3.py 中获取 Solidity 恢复/需要错误原因

    我正在努力抓住要求 交易恢复时出错 但我得到了交易的哈希值 我正在使用web3 py def addParticipants request web3 Web3 HTTPProvider settings Blockchain IP add
  • 使用有限的数据寻找多边形的中心

    我正在实施 Voronoi 曲面细分 然后进行平滑 为了平滑 我打算做劳埃德松弛 但我遇到了一个问题 我使用以下模块来计算 Voronoi 边 https bitbucket org mozman geoalg src 5bbd46fa22
  • NHibernate 异常:无法初始化集合,列名无效。流畅的映射。也许是多对一的问题?

    我对通过 NHibernate 遇到的异常感到困惑和沮丧 对于这篇文章的篇幅 我深表歉意 但我已尝试提供适当的详细信息来充分解释该问题 以获得一些帮助 事实如下 我有一个Person包含属性的类BillingManager 这也是一个Per
  • 是否有用于阻塞 boost::asio TCP 连接的 boost::iostreams (双向)设备?

    我正在调查可移植的 C 库 阻止对文件系统和网络的 I O 访问 它looks like boost filesystem boost iostreams and boost asio将由他们三人共同完成这项工作 需要明确的是 我目前对异步
  • 在 Winforms (C#) 中使用 MVP 模式的后台工作程序

    我一直在尝试使用 MVP 模式重构应用程序的意大利面条代码 但现在我正在为此苦苦挣扎 具有调用 DoWork 方法 后台工作者 的按钮的表单 这是一个很长的操作 我的问题是 如果我将长操作从视图移到演示器中 那么如何将此操作的进度更改发送到
  • 在线更新C#程序

    问候 如果这个问题已经被问过 我很抱歉 我尝试过使用搜索功能 但找不到适合我情况的答案 我有一个真正简单的 C 表单应用程序 只有 1 个文件 一个 exe 我目前通过 4shared 分发了此内容 人们可以随意下载 然而 每次我对程序进行
  • Matplotlib 颜色图 – 为每个图形/线条/主题选择不同的颜色

    我创建了一个读取并绘制 txt 文件及其内容 数字 值 的脚本 每个 txt 文件位于不同的文件夹中 每个文件夹又代表数据来源的一个主题 这段代码工作正常 Python 读取每个 txt 文件并将 23 个单独的图形 线条绘制成一个图 Py
  • jQuery 验证代码如何工作

    我发现这个教程使用 jQuery 和验证插件来验证表单输入 请参阅此处的工作示例 http jsfiddle net nK7Pw http jsfiddle net nK7Pw 这似乎工作正常 但是我有一个问题 在html部分中 没有提到错
  • Rails 4 更新嵌套属性

    更新嵌套属性附加而不是更新有很多关系 我正在尝试使用 Rails 4 Update attributes Class Person
  • Xamarin 表单 MessagingCenter 取消订阅未按预期工作

    当我在应用程序中多次来回导航时 MessagingCenter Subscribe 内编写的功能会被多次调用 但每次在订阅之前 我都会在构造函数中取消订阅 如下所示 但它仍然不起作用 MessagingCenter Unsubscribe
  • 提交表单后JQuery发送post请求?

    你好朋友 这是我的代码 用于表单提交 然后发送帖子链接 但表单提交成功 然后不发送帖子链接 document getElementById pitch image path form submit function e post submi
  • 应替换现有类型,添加新类型

    我有一个基地std vector和一个std initializer list
  • C编码:只读取带小数的浮点数,拒绝整数和特殊字符

    我正在尝试用 C gcc 编写代码以仅接受带小数的浮点数并拒绝整数 特殊字符 字母数字条目 有效条目是 1 23 3 45 6 77 无效条目 abc e34 834ww 6 9 还有一些不是浮动的废话 这是我尝试过的 include
  • 如何获取 Rails 控制器中活动存储中存储的附件的 URL

    如何获取存储在 Rails 控制器的活动存储中的 has one 模型附件的 URL 因此 我可以将其作为完整链接作为 json 中的 api 发送 到目前为止 我已经尝试过以下方法 但每个方法都给出了不同的问题 current user
  • 组合两个 matplotlib 颜色图

    我想将两个颜色图合并为一个 这样我就可以使用一个cmap一个用于负值 另一个用于正值 目前 我使用屏蔽数组来完成此操作 并用一张图像绘制一张图像cmap以及另一个图像与另一个图像 结果是 有以下数据 dat np random rand 1
  • 使用 Clearcase 递归签入

    我想将一个目录和所有子目录签入到透明案例中 有具体的命令可以实现吗 目前我正在进入每个目录并手动检查每个文件 我会推荐这个问题 https stackoverflow com questions 33577 how do i perform
  • 如何在 JavaScript 中循环遍历 JSON 关联数组?

    我从服务器收到 JSON 响应 并且必须在 javascript 中循环遍历数组并获取值 但我似乎无法循环遍历它 数组的 JSON 响应如下所示 1 Schools 20 Profiles 31 Statistics 44 Messages
  • 在 Facelet 模板中包含非 Facelet 内容

    有没有办法将 html 文件的内容插入到 Facelet 模板中 Facelets 标签不起作用 因为它仅用于包含 Facelet 内容 换句话说 我正在寻找相当于 JSP include 指令的 Facelets 我可能不明白你需要什么
  • 如何等待一组异步回调函数?

    我的代码在 javascript 中看起来像这样 forloop async call returns an array to its callback 所有这些异步调用完成后 我想计算所有数组的最小值 我怎样才能等到他们所有人呢 我现在唯