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.
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.
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éthode | Comportement en cas d'échec |
|---|---|
Promise.all | Rompt immédiatement, les valeurs déjà obtenues sont perdues |
Promise.allSettled | Ne 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.
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
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.
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.
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.