NodeJS 等待不等待 HTTP 调用完成

Ale*_*hek 1 javascript node.js promise async-await

我有一个对象数组,我正在使用 async forEach 循环遍历该数组,并使用 Axios 发出 HTTP get 请求。我告诉编译器在继续之前等待 axios 完成,但由于某种原因 console.log(data) 仍然在 console.log(ret) 之前运行

我认为这可能是因为 forEach 循环在遇到等待并继续时就被跳过了,但我不知道如何解决这个问题

data.forEach(async (e, i) => {
    let req = `https://api.darksky.net/forecast/7e12d816d7818a03901fa6a72e6802f5/${e.lat},${e.log},${Math.floor(e.start_time / 1000)}?units=si`
    let ret = await axios(req)
    console.log(ret)
    data[i]['weather'] = ret.data.currently.summary
    data[i]['cloudCover'] = ret.data.currently.cloudCover
})

console.log(data)
Run Code Online (Sandbox Code Playgroud)

这是我看到的输出(请注意,第一个数组理论上应该具有 'weather' 和 'cloudCover' 属性,因为它们是附加的)

[ { start_time: 1548952405372,
    end_time: 1548953096266,
    lat: 59.57644286,
    log: 20.16817143 },
  { start_time: 1548958463054,
    end_time: 1548959597889,
    lat: 59.57644286,
    log: 20.16817143 },
  { start_time: 1548964774667,
    end_time: 1548966048587,
    lat: 59.57644286,
    log: 20.16817143 } ]

{ status: 200,
  statusText: 'OK',
  headers: 
   { date: 'Wed, 10 Jul 2019 02:57:13 GMT',
     'content-type': 'application/json; charset=utf-8',
     'content-length': '10354',
     connection: 'close',
     'x-authentication-time': '705ms',
     'x-forecast-api-calls': '13',
     'cache-control': 'max-age=86400',
Run Code Online (Sandbox Code Playgroud)

Mik*_*ans 5

事实上,forEach 不等待任何东西:你给了它一个async函数,所以它可以为它安排一个开始调用,并立即转移到下一个函数,因为没有什么可以等待的:作为一个异步函数,它的返回值是一个 Promise,而不是真实的数据。

如果您想等到所有异步功能都完成,那么您必须使用Promise.all

async runThisStuff() {
  await Promise.all(data.map(async (e, i) => {
    let url = `...`
    let ret = await axios(url);
    console.log(ret)
    data[i]['weather'] = ret.data.currently.summary
    data[i]['cloudCover'] = ret.data.currently.cloudCover
  });

  console.log(data);
}
Run Code Online (Sandbox Code Playgroud)

如果您想在全局上下文中执行此操作,则不能等待Promise.all(因为您只能awaitasync函数内部),并且您必须使用正常的 promise then

Promise.all(
  data.map(async(...) => { ... })
).then(() => {
  console.log(data)
});
Run Code Online (Sandbox Code Playgroud)