Attendi le iterazioni array.map in Promise.all [duplicate]

Dec 06 2020

Ho il seguente codice che dovrebbe aggiungere articoli per i clienti se non esistono già. L'esecuzione dovrebbe essere parallela.

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

Il problema è che l'esecuzione non è in attesa di createCustomerItemessere risolta nei casi di!productExists)

Questo è il registro

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.

Naturalmente All items should not be presentdovrebbe venire per ultimo.

Quando tutti gli elementi esistono già, il processo sembra buono.

Risposte

JulienD Dec 06 2020 at 18:46

Prova con flatMap:

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

Invece di restituire un array di array di Promises, appiattirà il contenuto a un semplice array di Promises, che è ciò che ci si Promise.allaspetta.

NB Non è chiaro dalla tua domanda se il raggruppamento di articoli per cliente debba essere conservato. In tal caso, notare che questa soluzione modifica la struttura dei dati in un elenco appiattito, quindi si perde il raggruppamento. O aggiungine un po ' customerIdnei tuoi itemo prova il suggerimento di @ blex nei commenti.

ShashanSooriyahetti Dec 06 2020 at 18:56

puoi fare qualcosa di simile

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

risultati

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

demo sorgente