then() en JavaScript : enchaîner les traitements sur une promesse

then() enregistre le traitement à appliquer quand une promesse est tenue, et renvoie une nouvelle promesse : chaînage, erreurs et comparaison avec await.
3 min de lecture
Believemy logo

Une promesse ne rend pas sa valeur, elle la remet. Il faut donc lui indiquer d'avance à qui, et then est le guichet prévu pour cela.

Sa vraie force n'est pas de recevoir la valeur, mais de renvoyer à son tour une promesse. C'est ce détail qui transforme une suite d'étapes en une colonne lisible.


Définition

then(traitement) enregistre une fonction à exécuter lorsque la Promise est tenue, et renvoie une nouvelle promesse portant le résultat de ce traitement. Chaque maillon nourrit le suivant.

JAVASCRIPT
Promise.resolve(2)
  .then((v) => v * 3)                      // 6
  .then((v) => Promise.resolve(v + 1))     // 7, la promesse est déballée
  .then((v) => console.log("valeur", v));  // valeur 7

Le deuxième maillon rend une promesse et non un nombre : la chaîne l'attend et transmet sa valeur, sans jamais produire une promesse de promesse. Un return de valeur simple et un return de promesse se comportent donc pareil.


Ce qui se passe quand ça casse

Un throw dans un then saute tous les maillons suivants et va directement au premier catch rencontré. Après quoi la chaîne repart normalement.

JAVASCRIPT
Promise.resolve("dossier")
  .then(() => { throw new Error("coupure réseau"); })
  .then(() => console.log("jamais exécuté"))
  .catch((err) => console.log("attrapé :", err.message))
  .then(() => console.log("la chaîne repart"));

// attrapé : coupure réseau
// la chaîne repart

Un seul catch en fin de chaîne couvre donc toutes les étapes, alors qu'un style à callback aurait demandé un test d'erreur à chaque niveau.


Le second argument, et pourquoi on l'évite

then accepte une deuxième fonction, appelée en cas de rejet. Elle ressemble à catch, sans en avoir la portée.

ÉcritureCe qu'elle couvre
then(ok, echec)Le rejet arrivé avant, jamais l'erreur lancée par ok
then(ok).catch(echec)Le rejet arrivé avant et l'erreur lancée par ok

Ces deux colonnes expliquent la préférence générale pour catch : le second argument laisse passer l'erreur du traitement qu'il accompagne, ce qui produit un rejet non géré difficile à retrouver.

Bon à savoir

then ne s'exécute jamais dans le tour courant, même sur une promesse déjà tenue. Le traitement part dans la file des microtâches et attend la fin du code en cours, ce qui garantit un ordre stable quelle que soit la vitesse de l'opération.


Questions fréquentes

Question

Faut-il préférer then ou await ?

await l'emporte dès qu'il y a plusieurs étapes dépendantes ou une logique conditionnelle, parce que le code redevient linéaire. then reste plus court sur une transformation unique, et il est le seul disponible en dehors d'une fonction async dans les environnements anciens.


Question

Pourquoi mon then reçoit-il undefined ?

Parce que le maillon précédent n'a rien renvoyé. Une fonction fléchée à accolades a besoin d'un return explicite : (v) => { v * 2 } ne rend rien, contrairement à (v) => v * 2. C'est l'oubli le plus courant dans une chaîne.


Question

Peut-on brancher plusieurs then sur la même promesse ?

Oui, et ce n'est pas la même chose qu'un chaînage. Deux then posés sur la même variable reçoivent tous deux la valeur d'origine et créent deux branches indépendantes, alors qu'un chaînage fait passer la valeur de maillon en maillon.

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.