Promise.all() en JavaScript : attendre plusieurs promesses à la fois

Promise.all() lance plusieurs promesses ensemble et rend toutes leurs valeurs dans l'ordre, ou échoue au premier rejet : usages, pièges et alternatives.
3 min de lecture
Believemy logo

Trois appels réseau indépendants, exécutés l'un après l'autre, prennent la somme de leurs durées. Lancés ensemble, ils prennent celle du plus lent.

C'est exactement le gain qu'apporte Promise.all, et c'est la raison pour laquelle on le rencontre dans presque toute page qui charge des données.


Définition

Promise.all(liste) prend une liste de promesses et renvoie une promesse unique, tenue avec le tableau de toutes les valeurs quand la dernière est arrivée, rompue dès qu'une seule échoue.

JAVASCRIPT
const differe = (v, ms) => new Promise((r) => setTimeout(() => r(v), ms));

async function charger() {
  const [profil, factures] = await Promise.all([
    differe({ nom: "Chloé" }, 120),
    differe([{ montant: 19 }], 80),
  ]);
  console.log(profil.nom, factures.length);   // Chloé 1
}

charger();

La Destructuration du résultat est l'écriture habituelle. Les appels sont partis en même temps, donc l'attente totale vaut celle du plus long, pas la somme des deux.


L'ordre est celui de la liste, pas celui des réponses

Point souvent mal compris : le tableau rendu suit l'ordre dans lequel les promesses ont été fournies. La plus rapide n'arrive pas en première position, elle reste à sa place.

Cette garantie rend le résultat utilisable directement, sans avoir à identifier quelle valeur correspond à quel appel. Elle permet aussi de construire la liste avec Array.map() sur une collection.

JAVASCRIPT
const ids = [1, 2, 3];

async function lireTout() {
  const lignes = await Promise.all(
    ids.map((id) => differe("ligne " + id, 10 * id))
  );
  console.log(lignes);   // [ 'ligne 1', 'ligne 2', 'ligne 3' ]
}

lireTout();


Le premier échec l'emporte

Un seul rejet rompt la promesse globale sur-le-champ, sans attendre les autres. Les promesses restantes ne sont pas annulées pour autant : elles continuent, et leur résultat est simplement perdu.

MéthodeComportement en cas d'échec
Promise.allRompt immédiatement, les valeurs déjà obtenues sont perdues
Promise.allSettledNe rompt jamais, rend l'issue de chacune

Ces deux lignes suffisent à choisir : all pour des données toutes indispensables, allSettled pour un tableau de bord où une tuile en panne ne doit pas vider la page.

Bon à savoir

Une promesse rompue dont personne ne lit le rejet, parce que all a déjà échoué ailleurs, reste un rejet non géré aux yeux du moteur. Sous Node.js, cela peut arrêter le processus : c'est un argument de plus pour allSettled quand les appels sont vraiment indépendants.


Questions fréquentes

Question

Que rend Promise.all([]) ?

Une promesse tenue avec un tableau vide, réglée immédiatement. C'est le comportement souhaitable : une boucle qui ne produit aucun appel n'a pas à être traitée à part, la chaîne se poursuit sans condition supplémentaire.


Question

Peut-on y mettre autre chose que des promesses ?

Oui. Toute valeur simple présente dans la liste est convertie en promesse déjà tenue et ressort telle quelle. Mélanger une valeur en cache et un appel réseau dans la même liste fonctionne donc sans précaution particulière.


Question

Y a-t-il une limite au nombre de promesses ?

Pas côté langage, mais côté serveur oui. Lancer mille requêtes d'un coup sature la connexion et déclenche souvent une limitation de débit. Au-delà de quelques dizaines d'appels, découpez la liste en paquets traités les uns après les autres, ou utilisez une petite file d'attente.

Termes connexes

Découvrez notre glossaire JavaScript

Tous les mots de JavaScript expliqués simplement : mots-clés, objets natifs, méthodes, erreurs et concepts. Définitions claires et exemples qui tournent, pour apprendre et pour se dépanner.

Partager cet article

Tu veux nous aider ? Fais un lien vers cet article sur tes réseaux ou encore mieux : sur ton site, dans un article ou dans ta newsletter.