Tunggu iterasi array.map di Promise.all [duplikat]
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 createCustomerItem
penyelesaian 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 present
harus datang terakhir.
Ketika semua item sudah ada, maka prosesnya terlihat bagus.
Jawaban
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.all
diharapkan.
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 customerId
di item
s Anda , atau coba saran @ blex di komentar.
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