Espere las iteraciones de array.map en Promise.all [duplicado]
Tengo el siguiente código que debería agregar elementos para los clientes si aún no existen. La ejecución debe realizarse en paralelo.
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`);
El problema es que la ejecución no está a la espera de createCustomerItem
resolverse en los casos de!productExists)
Este es el 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 present
debería ser el último.
Cuando todos los elementos ya existen, el proceso se ve bien.
Respuestas
Prueba con flatMap:
await Promise.all(
customers.flatMap(async (customer) => {
return customer.items.map(async (item) => {
En lugar de devolver un conjunto de promesas, aplanará el contenido a un conjunto simple de promesas, que es lo que se Promise.all
espera.
NB De su pregunta no resulta evidente si es necesario conservar la agrupación de artículos por cliente. Si es así, tenga en cuenta que esta solución cambia la estructura de datos a una lista plana, por lo que pierde la agrupación. Agregue algunos customerId
en sus item
mensajes de correo electrónico o pruebe la sugerencia de @ blex en los comentarios.
puedes hacer algo como esto
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();
resultados
Start
["apple", "grape", "pear"]
End
demostración de la fuente