Promise en JavaScript : gérer un résultat qui arrivera plus tard

Une Promise représente une valeur qui n'existe pas encore : ses trois états, then et await, et les quatre façons d'en attendre plusieurs.
3 min de lecture
Believemy logo

Un appel réseau met deux cents millisecondes à répondre. JavaScript, lui, ne sait pas attendre : il déroule ses instructions sans s'arrêter. Il a donc fallu un moyen d'annoncer ce qu'il faudra faire quand la réponse arrivera, sans figer la page.

Une promesse est cet objet intermédiaire : un résultat qui n'existe pas encore, et n'existera peut-être jamais.


Définition

Une Promise est un objet qui représente l'issue d'une opération asynchrone : une valeur livrée plus tard, ou un échec. On ne récupère pas cette valeur directement, on enregistre d'avance le traitement à lui appliquer.

JAVASCRIPT
const lireFacture = async (id) => {
  if (id !== 42) throw new Error("Facture introuvable");
  return { id, montant: 19 };
};

lireFacture(42)
  .then((f) => console.log(f.montant))   // 19
  .catch((err) => console.log(err.message))
  .finally(() => console.log("terminé"));

then reçoit la valeur en cas de succès, catch reçoit l'Error en cas d'échec, finally s'exécute dans les deux cas. Les trois renvoient une nouvelle promesse, d'où l'enchaînement.


Les trois états

ÉtatCe qu'il signifieCe qui l'amène
En attenteLe résultat n'est pas connuL'état de départ
TenueUne valeur est disponibleUn resolve ou un return
RompueUne erreur est disponibleUn reject ou un throw

Le passage est définitif : le résultat ne bouge plus.

Bon à savoir

Une promesse démarre quand elle est créée, pas quand on l'attend : appeler une fonction asynchrone lance le travail tout de suite, même si le await arrive dix lignes plus bas.


await, la même chose en plus lisible

Dans une fonction async, await met la suite en pause jusqu'au règlement de la promesse, puis rend sa valeur. Les échecs redeviennent attrapables par un try.

JAVASCRIPT
async function afficherFacture(id) {
  try {
    const facture = await lireFacture(id);
    console.log(facture.montant);
  } catch (err) {
    console.log("Indisponible :", err.message);
  }
}

Le code se lit de haut en bas alors qu'il ne s'exécute pas dans cet ordre, et le gain grandit avec chaque appel enchaîné.


Attendre plusieurs promesses

MéthodeCe qu'elle rend
Promise.allToutes les valeurs, ou le premier échec
Promise.allSettledL'issue de chacune, sans jamais échouer
Promise.raceLa première réglée, succès ou échec
Promise.anyLa première tenue, les échecs étant ignorés
JAVASCRIPT
async function toutCharger() {
  const [profil, factures] = await Promise.all([
    lireProfil(),
    lireFactures(),
  ]);
  console.log(profil, factures);   // les deux appels ont couru ensemble
}


Questions fréquentes

Question

Faut-il encore écrire new Promise ?

Rarement. Toute fonction async renvoie déjà une promesse, et les interfaces modernes en produisent une d'elles-mêmes. Le constructeur ne sert plus qu'à emballer une interface à fonctions de rappel, comme setTimeout.

Question

Que se passe-t-il si personne n'attrape un rejet ?

L'échec remonte au moteur sous forme de rejet non géré : dans un navigateur il finit dans la console, sous Node.js il arrête le processus depuis la version 15. Une promesse sans catch est un risque réel.

Question

Enchaîner les await ou passer par Promise.all ?

Cela dépend des liens entre les appels. Si le second a besoin du résultat du premier, la séquence s'impose. Sinon, les lancer ensemble divise l'attente par leur nombre, un réflexe travaillé dans la formation JavaScript.

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.