Promise.all [duplicate]에서 array.map 반복을 기다립니다.

Dec 06 2020

고객이 아직 존재하지 않는 경우 고객을 위해 항목을 추가해야하는 다음 코드가 있습니다. 실행은 병렬로 이루어져야합니다.

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`);

문제는 다음과 같은 경우 실행이 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.

당연히 All items should not be present마지막에 와야합니다.

모든 항목이 이미 존재하면 프로세스가 좋아 보입니다.

답변

JulienD Dec 06 2020 at 18:46

시도해보십시오 flatMap:

await Promise.all(
    customers.flatMap(async (customer) => {
        return customer.items.map(async (item) => {

Promise 배열을 반환하는 대신 내용을 Promise의 간단한 배열로 평면화합니다 Promise.all.

NB 고객 당 품목 그룹을 보존해야하는지 질문에 대해서는 명확하지 않습니다. 그렇다면이 솔루션은 데이터 구조를 평면화 된 목록으로 변경하므로 그룹화가 손실됩니다. s 에 일부 customerId를 추가 item하거나 의견에 @blex의 제안을 시도 하십시오 .

ShashanSooriyahetti Dec 06 2020 at 18:56

당신은 이렇게 할 수 있습니다

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();

결과

Start
["apple", "grape", "pear"]
End

소스 데모