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 :
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 ?