[英]Node.js - Wait for multiple async calls to finish before continuing in code
所以基本上我有一个带有异步功能的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;
});
这里最简单的方法是直接或通过async
/ await
语法使用promise。 在这种情况下,可能直接。
首先,您必须使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]));
});
}
请注意,在该循环中对foo
使用const
或let
而不是var
是很重要的,因为then
回调会关闭它。 看到这个问题的答案,为什么const
和let
,使这项工作。
仅当前一个工作完成后,才会进行每次write
操作。
然后等待整个过程完成:
p.then(() => {
// All done
});
您还没有使用 write
请求中的布尔值显示任何内容,但是它们可以(作为数组)作为来自write
的promise的分辨率值使用。
该过程的第二部分,我们称为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
});
...或者如果这也在 async
函数中:
await doTheWrites();
使函数异步并等待调用:
async function write(foo) {
for(const url of foo) {
await asyncFunctionCall(url);
}
}
(async function() {
for(const foo of bar) {
await write(foo);
}
})()
那将一个接一个地执行。 要并行执行它们,请使用Promise.all:
const write = foo => Promise.all(foo.map(asyncFunctionCall));
Promise.all(bar.map(write))
.then(() => console.log("all done"));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.