Attendez les itérations de array.map dans Promise.all [duplicate]
J'ai le code suivant qui devrait ajouter des éléments pour les clients s'ils n'existent pas déjà. L'exécution doit se faire en parallèle.
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`);
Le problème est que l'exécution n'attend pas createCustomerItem
de résolution dans les cas de!productExists)
Ceci est le journal
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.
Naturellement All items should not be present
devrait venir en dernier.
Lorsque tous les éléments existent déjà, le processus semble bon.
Réponses
Essayez avec flatMap:
await Promise.all(
customers.flatMap(async (customer) => {
return customer.items.map(async (item) => {
Au lieu de renvoyer un tableau de tableaux de promesses, il aplatira le contenu en un simple tableau de promesses, ce qui est Promise.all
attendu.
NB Il ne ressort pas de votre question si le regroupement des articles par client doit être conservé. Si tel est le cas, notez que cette solution modifie la structure de données en une liste aplatie, vous perdez donc le regroupement. Ajoutez-en quelques-uns customerId
dans vos item
s ou essayez la suggestion de @ blex dans les commentaires.
tu peux faire quelque chose comme ça
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();
résultats
Start
["apple", "grape", "pear"]
End
démo source