รอการทำซ้ำ array.map ใน Promise.all [ซ้ำกัน]
ฉันมีรหัสต่อไปนี้ที่ควรเพิ่มสินค้าให้กับลูกค้าหากไม่มีอยู่แล้ว การดำเนินการควรเป็นแบบคู่ขนาน
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ควรมาเป็นอันดับสุดท้าย
เมื่อมีรายการทั้งหมดแล้วกระบวนการก็ดูดี
คำตอบ
ลองใช้flatMap:
await Promise.all(
customers.flatMap(async (customer) => {
return customer.items.map(async (item) => {
แทนที่จะส่งคืนอาร์เรย์อาร์เรย์ของคำสัญญามันจะทำให้เนื้อหาแบนราบเป็นอาร์เรย์ง่ายๆซึ่งเป็นสิ่งที่Promise.allคาดหวัง
หมายเหตุไม่ชัดเจนจากคำถามของคุณว่าการจัดกลุ่มสินค้าต่อลูกค้าจำเป็นต้องได้รับการอนุรักษ์หรือไม่ หากเป็นเช่นนั้นโปรดทราบว่าโซลูชันนี้เปลี่ยนโครงสร้างข้อมูลเป็นรายการแบบแบนดังนั้นคุณจะสูญเสียการจัดกลุ่ม เพิ่มบางส่วนcustomerIdในitems ของคุณหรือลองคำแนะนำของ @ blex ในความคิดเห็น
คุณสามารถทำสิ่งนี้ได้
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
แหล่งที่มา การสาธิต