如何在node.js中等待带有异步请求的循环完成?

ham*_*121 5 asynchronous for-loop node.js

我想在node.js中发出多个请求,以获取几个外部API响应,并将它们组合为一个数组。我正在使用for循环来实现这一点。这是我的代码:

res.setHeader('Content-Type', 'application/json');
const sub = req.query.days_subtract;
const enddate = req.query.end_date; 

var array = [];

for (var i = 0; i < sub; i++) {
  request("https://api.nasa.gov/planetary/apod?date=" + subtractDate(enddate, i) + "&api_key=DEMO_KEY", function(error, response, body) {
    array.push(body); 
    // console.log(body);
  });
}
res.send(array);
Run Code Online (Sandbox Code Playgroud)

但是这段代码始终会返回[]。我知道这是因为for循环仅启动这些异步请求,但并不等待它们完成。我尝试使用async / await,但还是没有用。那么,如何等待此循环完成请求的获取并完成将请求推送到数组以便可以将其显示给用户呢?

Ayu*_*pta 9

对于您的用例,使用awaitwith Promise.all可能是最有效的解决方法。您的代码应如下所示:

res.setHeader('Content-Type', 'application/json');
const sub = req.query.days_subtract;
const enddate = req.query.end_date;

var promiseArray = [];

for (var i = 0; i < sub; i++) {
    promiseArray.push(new Promise((resolve, reject) => 
        request("https://api.nasa.gov/planetary/apod?date=" + subtractDate(enddate, i) + "&api_key=DEMO_KEY", function(error, response, body) {
        if (err) reject(err);
        resolve(body)
    })))
}
res.send(await Promise.all(promiseArray));
Run Code Online (Sandbox Code Playgroud)


Kon*_*Kon 6

使用类似request-promise 的东西。如果您在 for 循环中等待每个请求,则所有请求都是按顺序完成的。如果每个请求都是独立的,不需要一个接一个地完成,这是低效的。处理此类事情的最佳方法是并行执行所有操作,然后等待它们全部完成。这是通过创建一系列请求承诺然后使用await Promise.all(promiseArray)等待所有承诺解决来完成的。

var promises = [];

for (var i = 0; i < sub; i++) {
  const promise = request("https://api.nasa.gov/planetary/apod?date=" + subtractDate(enddate, i) + "&api_key=DEMO_KEY");
  promises.push(promise);
}

const array = await Promise.all(promises);
Run Code Online (Sandbox Code Playgroud)