Promise utiliser les promesses

Définition

Une promesse est un objet ( Promise ) qui représente la complétion ou l’échec d’une opération asynchrone.

La plupart du temps, on consomme des promesses et c’est donc ce que nous verrons dans la première partie de ce guide pour ensuite expliquer comment les créer.

En résumé, une promesse est un objet qui est renvoyé et auquel on attache des callbacks plutôt que de passer des callbacks à une fonction.

Ainsi, au lieu d’avoir une fonction qui prend deux callbacks en arguments :

 1 function faireQqcALAncienne(successCallback, failureCallback){
 2   console.log("C'est fait");
 3   // réussir une fois sur deux
 4   if (Math.random() > .5) {
 5     successCallback("Réussite");
 6   } else {
 7     failureCallback("Échec");
 8   }
 9 }
10
11 function successCallback(résultat) {
12   console.log("L'opération a réussi avec le message : " + résultat);
13 }
14
15
16 function failureCallback(erreur) {
17   console.error("L'opération a échoué avec le message : " + erreur);
18 }
19
20 faireQqcALAncienne(successCallback, failureCallback);

On aura une fonction qui renvoie une promesse et on attachera les callbacks sur cette promesse :

 1 function faireQqc() {
 2   return new Promise((successCallback, failureCallback) => {
 3     console.log("C'est fait");
 4     // réussir une fois sur deux
 5     if (Math.random() > .5) {
 6       successCallback("Réussite");
 7     } else {
 8       failureCallback("Échec");
 9     }
10   })
11 }
12
13 const promise = faireQqc();
14 promise.then(successCallback, failureCallback);

ou encore :

1 faireQqc().then(successCallback, failureCallback);

Garanties

À la différence des imbrications de callbacks, une promesse apporte certaines garanties :

  • Les callbacks ne seront jamais appelés avant la fin du parcours de la boucle d’évènements JavaScript courante

  • Les callbacks ajoutés grâce à then seront appelés, y compris après le succès ou l’échec de l’opération asynchrone

  • Plusieurs callbacks peuvent être ajoutés en appelant then plusieurs fois, ils seront alors exécutés l’un après l’autre selon l’ordre dans lequel ils ont été insérés.

Chaînage des promesses

Un besoin fréquent est d’exécuter deux ou plus d’opérations asynchrones les unes à la suite des autres, avec chaque opération qui démarre lorsque la précédente a réussi et en utilisant le résultat de l’étape précédente. Ceci peut être réalisé en créant une chaîne de promesses.

La méthode then() renvoie une nouvelle promesse, différente de la première :

1 const promise = faireQqc();
2 const promise2 = promise.then(successCallback, failureCallback);

ou encore :

1 const promise2 = faireQqc().then(successCallback, failureCallback);

La deuxième promesse (promise2) indique l’état de complétion, pas uniquement pour faireQqc() mais aussi pour le callback qui lui a été passé (successCallback ou failureCallback) qui peut aussi être une fonction asynchrone qui renvoie une promesse.

Lorsque c’est le cas, tous les callbacks ajoutés à promise2 forment une file derrière la promesse renvoyée par successCallback ou failureCallback.

Autrement dit, chaque promesse représente l’état de complétion d’une étape asynchrone au sein de cette succession d’étapes.

Auparavant, l’enchaînement de plusieurs opérations asynchrones déclenchait une pyramide dantesque de callbacks :

1 faireQqc(function(result) {
2   faireAutreChose(result, function(newResult) {
3     faireUnTroisiemeTruc(newResult, function(finalResult) {
4       console.log('Résultat final :' + finalResult);
5     }, failureCallback);
6   }, failureCallback);
7 }, failureCallback);

Grâce à des fonctions plus modernes et aux promesses, on attache les callbacks aux promesses qui sont renvoyées.

On peut ainsi construire une chaîne de promesses :

 1 faireQqc().then(function(result) {
 2   return faireAutreChose(result);
 3 })
 4 .then(function(newResult) {
 5   return faireUnTroisiemeTruc(newResult);
 6 })
 7 .then(function(finalResult) {
 8   console.log('Résultat final : ' + finalResult);
 9 })
10 .catch(failureCallback);

Les arguments passés à then sont optionnels.

La forme catch(failureCallback) est un alias plus court pour then(null, failureCallback) .

Ces chaînes de promesses sont parfois construites avec des fonctions fléchées :

1 faireQqc()
2 .then(result => faireAutreChose(result))
3 .then(newResult => faireUnTroisiemeTruc(newResult))
4 .then(finalResult => {
5   console.log('Résultat final : ' + finalResult);
6 })
7 .catch(failureCallback);