Node.js - 在继续代码之前等待多个异步调用完成

2024-03-14

所以基本上我有一个 for 循环,其中有一个异步函数。问题是程序只是在循环后继续,我希望它等到循环中调用的所有异步函数都完成后再继续代码。

在我的代码中,“bar”是一个 json 数组,其中包含其他 json 数组。

function write(bla) { // gets called one after another

  for(var url in bla) {
    asyncFunctionCall(url); // Executed about 50 times, it has to run parallel
  }
  // Wait for all called functions to finish before next stuff happens and
  // write gets called again.

}

for(var foo in bar) {
  // Here i parse the json array "foo" which is in the json array "bar"
  write(foo[bla]); // bla is an array of multiple urls.
}

异步函数调用看起来像这样:

var request = require('request');

request(url, function (error, response, body) {
  if(typeof response !== 'undefined') {
    if((response.statusCode >= 400 && response.statusCode <= 451)
    || (response.statusCode >= 500 && response.statusCode <= 511))
      return true;
    return false;
  }
  return false;
});

这里最简单的方法是直接或通过使用 Promiseasync/await句法。在这种情况下,可能直接。

首先,你必须使asyncFunctionCall返回一个承诺。看起来你总是返回一个布尔值,所以在这种情况下我们总是会解决承诺:

function asyncFunctionCall(url) {
  return new Promise(resolve => {
    request(url, function (error, response, body) {
      if(typeof response !== 'undefined') {
        if((response.statusCode >= 400 && response.statusCode <= 451)
        || (response.statusCode >= 500 && response.statusCode <= 511)) {
          resolve(true);
          return;
        }
      }
      resolve(false);
    });
  });
}

然后,建立一系列你的承诺,并使用Promise.all等待所有这些都完成。这些调用运行在平行下:

function write(bla) { // gets called one after another
  const promises = [];
  for(var url in bla) {
    promises.push(asyncFunctionCall(url)); // Executed about 50 times.
  }
  return Promise.all(promises);
}

然后你可以建立一个包含所有承诺的链write所以他们串联运行:

let p = Promise.resolve();
for (const foo in bar) { // <== Notice `const`
  // See "Edit" below
  p = p.then(() => {
    // Here i parse the json object "foo" in the json array "bar"
    // bla is an array of multiple urls.
    return write(foo[bla]));
  });
}

请注意,使用这一点很重要const or let, not var, for foo在那个循环中,因为then回调结束;看这个问题的答案 http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example为什么const and let使之发挥作用。

每次致电write只有当前一个工作完成后才会进行。

然后等待整个过程完成:

p.then(() => {
  // All done
});

你还没有展示任何东西using布尔值来自write的请求,但它们可以(作为数组)作为承诺的解析值write.


该过程的第二部分,我们称之为write,也可以写成async函数可以使逻辑流程更清晰:

async function doTheWrites() {
  for (const foo in bar) {
    // Here i parse the json object "foo" in the json array "bar"
    // bla is an array of multiple urls.
    await write(foo[bla]);
  }
}

那么整体流程:

doTheWrites().then(() => {
  // All done
});

...或者如果这是also in an async功能:

await doTheWrites();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Node.js - 在继续代码之前等待多个异步调用完成 的相关文章

随机推荐

  • 启动时依赖 CLR 的程序集解析

    当程序启动时 CLR 是否尝试解析 不一定加载 所有依赖程序集 也就是说 依赖的大会决议是按需完成的吗 请注意 我不是在谈论 Assembly Load Reflective 类型的负载 JIT 编译器负责指导程序集的加载 以响应将 IL
  • 如何在 Blazor 中订阅 onscroll 事件?

    我试图对 Blazor 中的 onscroll 事件做出反应 以便在用户向下滚动网页时为图像设置动画 类似于此网站上的品牌徽标 https lebenswelten stgabriel at https lebenswelten stgab
  • 拖动按钮时 ScrollView 不滚动

    我有一个滚动视图 当它上面没有按钮时 它会滚动 现在确实如此 当拖动鼠标 在模拟器上 时 什么也没有发生 我认为是因为按钮被按下 我怎样才能做到这一点 发生这种情况是因为UIButton的子视图UIScrollView 我假设按钮在您的情况
  • 如何将原始 SQL 查询放入 Sequel 中

    我正在尝试将 SQL 代码转换为 Seqel 以从我的脚本运行它 我如何转换这个 select code count 1 as total from school districts group by code order by total
  • 从 SQL Server 中的 XML 选择空值

    我正在尝试从具有 null 作为属性之一的 XML 中进行选择 它没有返回 null 而是返回 0 我做错了什么 请参阅下面的代码进行复制 declare a xml select a
  • 将变量传递给jsp

    我有一个java类 public void doView RenderRequest renderRequest RenderResponse renderResponse throws IOException PortletExcepti
  • 使用 RxJava 进行电子邮件登录验证,可观察对象发出两次

    我正在制作一个简单的登录表单 电子邮件和密码 来尝试增强我的反应式编程技能 我在让电子邮件字段验证按照我想要的方式工作时遇到一些问题 这是我的代码 final Observable
  • 如何在 Linux 中获取文件创建日期?

    我正在处理一批文件 这些文件包含同一对象在其生命周期不同时间的信息 对它们进行排序的唯一方法是按创建日期 我正在使用这个 char buffer has the name of file struct stat buf FILE tf tf
  • select2 将类添加到所选选项

    我想添加类option在 select2 中 所以在我单击建议列表项后 它将添加自定义类添加到选择多个到主要的选择结构 这是示例代码
  • Go/Golang sql.DB 在函数中的重用

    sql Open 返回 sql DB 类型的变量 我有一个函数可以调用其他 10 个函数 这些函数都需要进行数据库调用 是否更正确 更有效 将 sql DB 指针发送到每个函数 或者 在每个函数中创建一个新的 sql DB 对象 Meani
  • 是否可以捕获 Ctrl+C 信号 (SIGINT) 并以“延迟”方式运行清理函数?

    I want to capture the Ctrl C SIGINT signal sent from the console and print out some partial run totals You can use the o
  • Swift 相当于 Ruby 的“each_cons”

    Ruby 红宝石有每个缺点 https ruby doc org core 2 1 0 Enumerable html method i each cons可以像这样使用 class Pair def initialize left rig
  • 如果枚举无法适合无符号整型,会发生什么情况?

    根据要求芭丝谢芭 https stackoverflow com users 2380830 bathsheba并作为后续问题 如果枚举不能适合整型 会发生什么 https stackoverflow com questions 39620
  • 获取时区的日期时间偏移

    我有一个代码 需要查找中欧时区与 UTC 的当前偏移量 我的代码部署在azure应用程序服务中 var offset DateTimeOffset Now Offset Hours DateTimeOffset Now Offset Min
  • 使用 Android 5.0 Activity 转换到具有 ViewPager 的 Activity 时出现问题

    因此 我们尝试创建从 ListView 中的图像到 ViewPager 图库中的图像的跨活动图像过渡 在执行此过渡时 我们看到动画在 ViewPager 完成加载 绘制之前发生 这会导致 ViewPager 上的图像闪烁 从而使动画看起来很
  • IOptionsMonitor 与 IOptionsSnapshot 之间的区别

    根据这个答案 https stackoverflow com a 46570073 1987788 IOptionsMonitor在 DI 容器中注册为单例并且能够通过以下方式检测变化OnChange事件订阅 它有一个CurrentValu
  • 带有当前时间戳的 Spring Roo 日期字段

    大多数数据库允许具有当前时间戳的字段 充当创建时间戳 例如在 MySQL 中 CREATE TABLE t ts TIMESTAMP DEFAULT CURRENT TIMESTAMP 如何在 Spring Roo 中实现这一点 找不到提示
  • 使用大量 CPU 的 Visual Studio Code

    我运行的是 Windows 10 VSCode 即使在空闲时也会占用 26 30 的 CPU 我试过code disable extensions在 CMD 中检查扩展是否导致问题 但我的性能与扩展相同 当我使用 sublime text
  • 向 UIScrollView 内的 UIImageView 添加捏合/缩放效果

    我有一个非常基本的屏幕共享iPhone应用程序 我已经使用a成功地将捏合 缩放效果添加到我的应用程序中UIImageView里面一个UIScrollView The UIImageView定期接收来自PC的屏幕内容 一切工作正常 但一旦我滚
  • Node.js - 在继续代码之前等待多个异步调用完成

    所以基本上我有一个 for 循环 其中有一个异步函数 问题是程序只是在循环后继续 我希望它等到循环中调用的所有异步函数都完成后再继续代码 在我的代码中 bar 是一个 json 数组 其中包含其他 json 数组 function writ