Tunggu iterasi array.map di Promise.all [duplikat]

Dec 06 2020

Saya memiliki kode berikut yang harus menambahkan item untuk pelanggan jika belum ada. Eksekusi harus paralel.

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

Masalahnya adalah bahwa eksekusi tidak menunggu createCustomerItempenyelesaian dalam kasus!productExists)

Ini lognya

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.

Tentu All items should not be presentharus datang terakhir.

Ketika semua item sudah ada, maka prosesnya terlihat bagus.

Jawaban

JulienD Dec 06 2020 at 18:46

Coba dengan flatMap:

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

Alih-alih mengembalikan larik larik Promises, itu akan meratakan konten menjadi larik sederhana Janji, yang Promise.alldiharapkan.

NB Tidak jelas dari pertanyaan Anda apakah pengelompokan item per pelanggan perlu dipertahankan. Jika ya, perhatikan bahwa solusi ini mengubah struktur data menjadi daftar yang diratakan, sehingga Anda kehilangan pengelompokan. Tambahkan beberapa customerIddi items Anda , atau coba saran @ blex di komentar.

ShashanSooriyahetti Dec 06 2020 at 18:56

Anda bisa melakukan sesuatu seperti ini

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

hasil

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

demo sumber