等待 Promise.all 中的 array.map 迭代

Ang*_*ant 6 javascript asynchronous node.js promise

我有以下代码,应该为客户添加项目(如果它们尚不存在)。执行应该是并行的。

await Promise.all(
    customers.map(async (customer) => {
        return customer.items.map(async (item) => {
            return new Promise(async (resolve) => {
                const productExists = someArray.some(
                    (arrayValue) => arrayValue === item.id
                );
                if (!productExists) {
                    logger.info(
                    `customer item ${item.id} does not exist, creating...`
                    );
                    await createCustomerItem(item.id);
                    logger.info(`customer item ${item.id} created.`);

                    someArray.push(item.id);
                } else {
                    logger.info(`customer item ${item.id} already exists, skipping...`);
                }
                resolve(true);
            });
        });
    })

);

logger.info(`All items should now be present`);
Run Code Online (Sandbox Code Playgroud)

问题是createCustomerItem在以下情况下执行不会等待解决!productExists)

这是日志

customer item 32310 does not exist, creating...
customer item ao does not exist, creating...
customer item ute does not exist, creating...
All items should not be present
customer item ao created.
customer item ute created.
customer item 32310 created.
Run Code Online (Sandbox Code Playgroud)

自然All items should not be present应该排在最后。

当所有项目都已存在时,该过程看起来不错。

Sha*_*tti 7

你可以做这样的事情

const fruitsToGet = ['apple', 'grape', 'pear']

const mapLoop = async () => {
  console.log('Start')

  const promises = await fruitsToGet.map(async fruit => {
    const numFruit = new Promise((resolve, reject) => {
      setTimeout(() => resolve(fruit), 1000)
    });
    return numFruit
  })
  const numFruits = await Promise.all(promises)
  console.log(numFruits)

  console.log('End')
}

mapLoop();
Run Code Online (Sandbox Code Playgroud)

结果

Start
["apple", "grape", "pear"]
End
Run Code Online (Sandbox Code Playgroud)

源码 演示

  • 这一行: `const Promise = waitfruitsToGet.map(asyncfruit` 不需要 `await` 也不需要 `async`,在这种情况下它是多余的。 (3认同)

Jul*_*enD 2

尝试使用flatMap

await Promise.all(
    customers.flatMap(async (customer) => {
        return customer.items.map(async (item) => {
Run Code Online (Sandbox Code Playgroud)

它不会返回 Promises 数组的数组,而是将内容扁平化为简单的 Promises 数组,这正是我们所Promise.all期望的。

注意:从您的问题来看,是否需要保留每个客户的商品分组并不明显。如果是这样,请注意,此解决方案将数据结构更改为扁平列表,因此您会丢失分组。要么customerId在你的items 中添加一些,要么尝试@blex 在评论中的建议。


归档时间:

查看次数:

37626 次

最近记录:

4 年,11 月 前