简体   繁体   English

Javascript 在循环中等待

[英]Javascript await inside a loop

I am trying to work with an api where I have to send a request for each item in a list.我正在尝试使用 api,我必须为列表中的每个项目发送一个请求。 However, I see that the loop doesn't seem to wait for every request, ie, the loop doesn't work as expected.但是,我看到循环似乎并没有等待每个请求,即循环没有按预期工作。 Here's the code below这是下面的代码

getInfo = async () => {
   const mylist = ["item1","item2","item3","item4","item5","item6","item7"]
   const responses = []
   const len = mylist.length
   for (let i = 0; i < len; i++) {
      //console.log("inside loop")
      await axios.get("some_url/"+mylist[i])
          .then(res => {
              responses.push(res.data)
          })
   }

When I run the program, all the console.log("inside loop") executes immediately without waiting for the request to be complete.当我运行程序时,所有的console.log("inside loop")立即执行,而无需等待请求完成。

How can I modify the code so as to wait for each response to be completed before updating the for loop counter variable?如何修改代码以便在更新 for 循环计数器变量之前等待每个响应完成?

You could try re-arranging the code to something like this.您可以尝试将代码重新排列为这样的内容。 But using a Promise.all with Array.prototype.map would be more idiomatic solution for the problem.但是将Promise.allArray.prototype.map Promise.all使用将是该问题的更惯用的解决方案。

await the async call (remove unnecessary .then call) and then console.log await async调用(删除不必要的.then调用)然后console.log

getInfo = async () => {
   const mylist = ["item1","item2","item3","item4","item5","item6","item7"]
   const responses = []
   const len = mylist.length
   for (let i = 0; i < len; i++) {
      responses.push((await axios.get("some_url/"+mylist[i])).data)
      console.log("inside loop")
   }
}

Internally, await is translated into a Promise chain.在内部, await被翻译成一个Promise链。 Since the for loop can't be transformed into a Promise-continuation, you'll need to convert it to a Promise-based construct.由于for循环无法转换为 Promise 延续,因此您需要将其转换为基于 Promise 的构造。

Depending on what you want to achieve there are multiple ways to go about it.根据您想要实现的目标,有多种方法可以实现。 Constructing the responses array could be done with a map statement.可以使用map语句构建responses数组。

const promises = mylist.map(item => {
   return axios.get("some_url/"+item).then(res => { return res.data; })
});
const data = await Promise.all(promises);

No manual pushing items around or fiddling with the array length.无需手动推动项目或摆弄阵列长度。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM