Node.js - 在继续代码之前等待多个异步调用完成 [英] Node.js - Wait for multiple async calls to finish before continuing in code

查看:178
本文介绍了Node.js - 在继续代码之前等待多个异步调用完成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

So basically i have a for loop with an async function in it. Problem is that the program just continues after the loop and i want it to wait until all async functions which were called in the loop are finished before the code continues.

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

In my code "bar" is a json array with other json arrays in it.

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.
}

异步函数调用如下所示:

The async function call looks something like this:

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


推荐答案

这里最简单的方法是直接使用promises或通过 async / 等待语法。在这种情况下,可能是直接的。

The simplest way here is to use promises, directly or via async/await syntax. In this case, probably directly.

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

First, you have to make asyncFunctionCall return a promise. It looks like you always return a boolean, so in this case we'll always resolve the promise:

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 等待所有这些完成。这些调用并行运行

Then, build up an array of your promises, and use Promise.all to wait for all of them to complete. These calls run in parallel:

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

然后你可以建立一个来自<$ c $的所有承诺链c>写,使它们连续运行:

Then you can build a chain of all of the promises from write so they run in series:

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 ,而不是 var foo 在该循环中,因为然后回调关闭它;请参阅此问题的答案,了解为什么 const 让它工作。

Note that it's important that you use const or let, not var, for foo in that loop, because the then callback closes over it; see this question's answers for why const and let make that work.

每次调用只会在上一个工作完成后才会生成。

Each call to write will only be made when the previous one's work is done.

然后等待整个过程完成:

Then wait for the whole process to complete:

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

您没有显示任何使用来自<$ c $的布尔值c>写的请求,但它们可用(作为数组)作为来自写入的承诺的分辨率值。

You haven't shown anything using the booleans from write's requests, but they're available (as an array) as the resolution value of the promise from write.

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

The second part of the process, where we're calling write, can also be written in an async function which may make the logical flow clearer:

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

...或者如果 async function:

...or if this is also in an async function:

await doTheWrites();

这篇关于Node.js - 在继续代码之前等待多个异步调用完成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆