【问题标题】:Async for of loop is not working as expected (JS) [duplicate]循环的异步未按预期工作(JS)[重复]
【发布时间】:2021-03-09 01:12:18
【问题描述】:

一开始,我是这样使用 forEach 的:

products.forEach(async (product) => {
    if (
      product.type === 'shows' &&
      product.isSoldOut &&
      product.otherData
    ) {
      delete product.brand.brandId
      product.brand.isTop = true
      const res = await api.create(product.brand)
      console.log(res)
    }
  })

但问题是它在其他调用之后被调用,而应该在它们之前调用。在这里检查了一些答案后,我切换到 for of 循环,以强制它在位于它之后的其他异步操作之前调用。但问题是它现在根本没有被调用。代码如下:

for (const product of products) {
        async () => {
    if (
      product.type === 'shows' &&
      product.isSoldOut &&
      product.otherData
    ) {
      delete product.brand.brandId
      product.brand.isTop = true
      const res = await api.create(product.brand)
      console.log(res)
    }
  }
}

怎么了?它根本没有被调用,我怎样才能强制这个位于循环中的异步调用在位于它之后的调用之前被调用?

【问题讨论】:

  • async () => { ... } - 这个嵌套函数(你从不调用)在 for-of 循​​环中做了什么?

标签: javascript ecmascript-6 async-await


【解决方案1】:

您的代码只是反复创建然后丢弃它从不调用的async 函数。但即使调用它也无济于事。

如果包含函数(出现此代码的函数)不是 async 函数,则该函数的逻辑将始终完成,然后您才能看到这些异步操作的任何结果。您不能直接观察同步函数中的异步结果。您可以在操作完成时使用Promise.allmap 获取回调:

// In a non-`async` function
Promise.all(products.map(async (product) => {
    if (
        product.type === 'shows' &&
        product.isSoldOut &&
        product.otherData
    ) {
        delete product.brand.brandId
        product.brand.isTop = true
        const res = await api.create(product.brand)
        console.log(res)
    }
}))
.then(() => {
    // It's all done now
})
.catch(error => {
    // There was an error
});

在包含函数返回之前,这些承诺完成回调不会运行。另请注意,这些操作是并行发生的(所有都开始并重叠运行),而不是串联(一次一个)。 (也可以串联,但您的forEach 是并行的,所以...)

如果包含函数是 async 函数,您可以根据需要切换到 for-of

// In an `async` function
for (const product of products) {
    if (
        product.type === 'shows' &&
        product.isSoldOut &&
        product.otherData
    ) {
        delete product.brand.brandId
        product.brand.isTop = true
        const res = await api.create(product.brand)
        console.log(res)
    }
}

请注意,这将依次启动每个操作,等待启动下一个操作,直到前一个操作完成。

【讨论】:

    猜你喜欢
    • 2018-12-02
    • 1970-01-01
    • 2021-12-08
    • 1970-01-01
    • 2018-05-29
    • 2019-04-19
    • 1970-01-01
    • 1970-01-01
    • 2018-05-05
    相关资源
    最近更新 更多