【问题标题】:Javascript await inside a loopJavascript 在循环中等待
【发布时间】:2020-09-20 19:27:46
【问题描述】:

我正在尝试使用 api,我必须为列表中的每个项目发送请求。 但是,我看到循环似乎并没有等待每个请求,即循环没有按预期工作。下面是代码

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)
          })
   }

当我运行程序时,所有console.log("inside loop") 立即执行,无需等待请求完成。

如何修改代码,以便在更新 for 循环计数器变量之前等待每个响应完成?

【问题讨论】:

  • 使用async await 语法时,不需要添加then 部分。您可以将 console.log 放在 await 语句之后。 const res = await axios.get()
  • .then() 的用法有点奇怪(cons res = await …; responses.push(res.data) 会更惯用),但它应该可以按预期工作。这是您的实际代码吗?

标签: javascript


【解决方案1】:

您可以尝试将代码重新排列为类似的内容。但是使用Promise.allArray.prototype.map 会是解决问题的更惯用的解决方案。

awaitasync 调用(删除不必要的.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")
   }
}

【讨论】:

    【解决方案2】:

    在内部,await 被转换为Promise 链。由于 for 循环无法转换为 Promise-continuation,因此您需要将其转换为基于 Promise 的构造。

    根据您想要实现的目标,有多种方法可以实现。 可以使用map 语句来构造responses 数组。

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

    无需手动推送项目或摆弄数组长度。

    【讨论】:

    • "既然 for 循环不能转换成 Promise-continuation" - 当然可以?
    • OP 明确抱怨“所有console.log("inside loop") 立即执行而不等待请求完成”,所以不,他们这样做 想要并发Promise.all 解决方案!它应该“等待每个响应完成之前”进入下一次迭代。
    猜你喜欢
    • 2020-10-04
    • 1970-01-01
    • 2015-09-10
    • 1970-01-01
    • 2023-01-20
    • 2018-09-25
    • 1970-01-01
    • 2015-07-03
    • 1970-01-01
    相关资源
    最近更新 更多