JavaScript: async/await avec forEach()

Ou comment remettre un peu d’ordre dans des traitements asynchrones.

Le problème : imprimer une série de dessins en respectant une chronologie pour la mise en page.

// La série de dessins
const serie = [
{ no: 1 },
{ no: 2 },
{ no: 3 },
{ no: 4 },
]

Pour cela, il nous faut donc la fonction qui va bien :

// La fonction qui imprime
const imprimer = (no) => {
console.log(`Impression du dessin n° : ${no}.`);
};

Hélas, l’impression n’est pas synchrone et met un certain délai à se réaliser. Corrigeons donc cette fonction pour qu’elle renvoie une promesse qui ne sera résolue qu’après un délai variable.

// La fonction qui prend un certain temps pour imprimer
const imprimer = async ({no, delai}) => {
return new Promise((resolve) => {
setTimeout(() => {
console.log(`Impression du dessin n° : ${no} après ${delai} ms.`);
resolve(no);
}, delai);
});
};

Précisons ces délais au niveau de la série de dessins :

const serie = [
{no: 1, delai: 2000},
{no: 2, delai: 500},
{no: 3, delai: 1000},
{no: 4, delai: 750}
];

Naïvement, pour imprimer notre série, nous pourrions utiliser la méthode forEach sur le tableau :

serie.forEach((dessin) => {
imprimer(dessin);
});

Mais c’est là que les problèmes commencent, mes dessins que j’avais bien ordonnés et que je pensais imprimer magnifiquement répartis sur mon document se retrouvent imprimés dans un ordre totalement aléatoire :

Impression du dessin n° : 2 après 500 ms.
Impression du dessin n° : 4 après 750 ms.
Impression du dessin n° : 3 après 1000 ms.
Impression du dessin n° : 1 après 2000 ms.

Une autre solution aurait été d’utiliser Promise.all() :

Promise.all(serie.map(imprimer))

Mais le résultat est le même :

Une des solutions est alors la suivante : Utiliser la fonction asynchrone suivante :

const asyncForEach = async (arr, callback) => {
for (let i = 0; i < arr.length; i++) {
await callback(arr[i], i, arr);
}
};

Et alors, mes impressions se déroulent bien dans l’ordre escompté :

Impression du dessin n° : 1 après 2000 ms.
Impression du dessin n° : 2 après 500 ms.
Impression du dessin n° : 3 après 1000 ms.
Impression du dessin n° : 4 après 750 ms.

Et voilà, le tour est joué. Et vous, comment faites-vous ?

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

This site uses Akismet to reduce spam. Learn how your comment data is processed.