Rxc*_*ard 9 javascript loops asynchronous node.js npm
所以基本上我有一个带有异步函数的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.
}
Run Code Online (Sandbox Code Playgroud)
异步函数调用看起来像这样:
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;
});
Run Code Online (Sandbox Code Playgroud)
T.J*_*der 10
这里最简单的方法是直接或通过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);
});
});
}
Run Code Online (Sandbox Code Playgroud)
然后,建立您的诺言数组,并用于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);
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以构建所有承诺的链,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]));
});
}
Run Code Online (Sandbox Code Playgroud)
请注意,在该循环中使用const或let而不是var,这一点很重要foo,因为then回调会关闭该循环。查看为什么这个问题的答案,const并let使它起作用。
write只有在上一个工作完成后,才会调用。
然后等待整个过程完成:
p.then(() => {
// All done
});
Run Code Online (Sandbox Code Playgroud)
您尚未使用write的请求中的布尔值显示任何内容,但它们可以作为数组中的promise的分辨率值使用(作为数组)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]);
}
}
Run Code Online (Sandbox Code Playgroud)
然后是整个过程:
doTheWrites().then(() => {
// All done
});
Run Code Online (Sandbox Code Playgroud)
...或者,如果这也是在一个async功能:
await doTheWrites();
Run Code Online (Sandbox Code Playgroud)