Promesses et async/attente en JavaScript : le guide ultime

Maîtrisez les promesses et async/wait en JavaScript avec ce guide complet ! Apprenez tout ce que vous devez savoir sur l'utilisation des promesses et async/wait en JavaScript.

Alors, commençons.

Pourquoi utiliser des promesses en JavaScript ?

ES6 a introduit les promesses en tant qu'implémentation native. Avant ES6, nous utilisions des rappels pour gérer les opérations asynchrones.

Comprenons ce que sont les rappels et quel problème lié aux rappels est résolu par les promesses.

Disons que nous avons une liste de messages et leurs commentaires respectifs, comme ceci :

const posts = [
  { post_id: 1, post_title: 'First Post' },
  { post_id: 2, post_title: 'Second Post' },
  { post_id: 3, post_title: 'Third Post' },
];

const comments = [
  { post_id: 2, comment: 'Great!'},
  { post_id: 2, comment: 'Nice Post!'},
  { post_id: 3, comment: 'Awesome Post!'},
];

Maintenant, nous allons écrire une fonction pour obtenir un message en passant l'identifiant du message. Si la publication est trouvée, nous récupérerons les commentaires liés à cette publication.

const getPost = (id, callback) => {
 const post = posts.find( post => post.post_id === id);
 if(post) {
   callback(null, post);
 } else {
   callback("No such post found", undefined);
 }
};

const getComments = (post_id, callback) => {
 const result = comments.filter( comment => comment.post_id === post_id);
 if(result) {
   callback(null, result);
 } else {
   callback("No comments found", undefined);
 }
}

Dans les fonctions getPostet ci-dessus getComments, s'il y a une erreur, nous la passerons comme premier argument. Mais si nous obtenons le résultat, nous appellerons la fonction de rappel et lui transmettrons le résultat comme deuxième argument.

Si vous connaissez Node.js, vous saurez qu'il s'agit d'un modèle très courant utilisé dans chaque fonction de rappel Node.js.

Utilisons maintenant ces fonctions :

getPost(2, (error, post) => {
    if(error) {
     return console.log(error);
    }
    console.log('Post:', post);
    getComments(post.post_id, (error, comments) => {
        if(error) {
          return console.log(error);
        }
        console.log('Comments:', comments);
    });
});

Après avoir exécuté le code ci-dessus, vous verrez la sortie suivante :

des postes

Résultat de l'appel de la fonction getPost et getComments

Voici une démo CodePen .

Comme vous pouvez le voir, nous avons la getCommentsfonction imbriquée dans le getPostrappel.

Imaginez maintenant si nous voulions également trouver les goûts de ces commentaires. Cela serait également imbriqué dans getCommentsle rappel, créant ainsi plus d'imbrication. Cela finira par rendre le code difficile à comprendre.

Cette imbrication des rappels est connue sous le nom d'enfer des rappels.

Vous pouvez voir que la condition de gestion des erreurs est également répétée dans le code, ce qui crée du code en double - ce n'est pas bon.

Donc, pour résoudre ce problème et permettre des opérations asynchrones, des promesses ont été introduites.

Que sont les Promesses en JavaScript ?

Les promesses sont l'une des parties les plus importantes de JavaScript, mais elles peuvent prêter à confusion et être difficiles à comprendre. De nombreux nouveaux développeurs, ainsi que des développeurs expérimentés, ont du mal à les saisir pleinement.

Qu'est-ce donc qu'une promesse ? Une promesse représente une opération asynchrone dont le résultat viendra dans le futur.

Avant ES6, il n'y avait aucun moyen d'attendre que quelque chose effectue une opération. Par exemple, lorsque nous voulions faire un appel API, il n'y avait aucun moyen d'attendre que les résultats reviennent.

Pour cela, nous avions l'habitude d'utiliser des bibliothèques externes comme JQuery ou Ajax qui avaient leur propre implémentation de promesses. Mais il n'y avait pas d'implémentation JavaScript des promesses.

Mais ensuite, des promesses ont été ajoutées dans ES6 en tant qu'implémentation native. Et maintenant, en utilisant les promesses dans ES6, nous pouvons effectuer nous-mêmes un appel d'API et attendre qu'il soit terminé pour effectuer une opération.

Comment créer une promesse

Pour créer une promesse, nous devons utiliser la Promisefonction constructeur comme ceci :

const promise = new Promise(function(resolve, reject) {
 
});

Le Promiseconstructeur prend une fonction comme argument et cette fonction reçoit en interne resolveet rejectcomme paramètres.

Les paramètres resolveet rejectsont en fait des fonctions que nous pouvons appeler en fonction du résultat de l'opération asynchrone.

A Promisepeut passer par trois états :

  • En attente
  • Rempli
  • Rejeté

Lorsque nous créons une promesse, elle est dans un état en attente. Lorsque nous appelons la resolvefonction, elle passe à l'état rempli, et si nous l'appelons, rejectelle passe à l'état rejeté.

Pour simuler l'opération de longue durée ou asynchrone, nous utiliserons la setTimeoutfonction.

const promise = new Promise(function(resolve, reject) {
 setTimeout(function() {
  const sum = 4 + 5;
  resolve(sum);
 }, 2000);
});

Ici, nous avons créé une promesse qui se résoudra à la somme de 4et 5après un délai d'attente de 2000 ms (2 secondes).

Pour obtenir le résultat de l'exécution réussie de la promesse, nous devons enregistrer un gestionnaire de rappel en utilisant .thencomme ceci :

const promise = new Promise(function(resolve, reject) {
 setTimeout(function() {
  const sum = 4 + 5;
  resolve(sum);
 }, 2000);
});

promise.then(function(result) {
 console.log(result); // 9
});

Ainsi, chaque fois que nous appelons resolve, la promesse renverra la valeur transmise à la resolvefonction que nous pouvons collecter à l'aide du .thengestionnaire.

Si l'opération échoue, nous appelons la rejectfonction comme ceci :

const promise = new Promise(function(resolve, reject) {
 setTimeout(function() {
  const sum = 4 + 5 + 'a';
  if(isNaN(sum)) {
    reject('Error while calculating sum.');
  } else {
    resolve(sum);
  }
 }, 2000);
});

promise.then(function(result) {
 console.log(result);
});

Ici, si sumn'est pas un nombre, nous appelons la rejectfonction avec le message d'erreur. Sinon, on appelle la resolvefonction.

Si vous exécutez le code ci-dessus, vous verrez la sortie suivante :

promesses_fcc

Résultat du rejet de la promesse sans gestionnaire de capture

Comme vous pouvez le voir, nous recevons un message d'erreur non intercepté avec le message que nous avons spécifié car l'appel de la rejectfonction génère une erreur. Mais nous n'avons pas ajouté de gestionnaire d'erreurs pour intercepter cette erreur.

Pour attraper l'erreur, nous devons enregistrer un autre rappel en utilisant .catchcomme ceci :

promise.then(function(result) {
 console.log(result);
}).catch(function(error) {
 console.log(error);
});

Vous verrez la sortie suivante :

error_catch

Résultat du rejet de la promesse avec le gestionnaire de capture

Comme vous pouvez le voir, nous avons ajouté le .catchgestionnaire, nous n'obtenons donc aucune erreur non détectée - nous enregistrons simplement l'erreur dans la console.

Cela évite également d'arrêter brutalement votre application.

Il est donc toujours recommandé d'ajouter le .catchgestionnaire à chaque promesse afin que votre application ne s'arrête pas à cause de l'erreur.

Quand utiliser resolveetreject

Prenons un exemple d'appel d'API.

Si vous effectuez un appel d'API et que l'appel d'API réussit, vous appelez la resolvefonction en lui transmettant le résultat de l'API en tant qu'argument.

Et si l'API échoue, vous appelez la rejectfonction en lui transmettant n'importe quel message en tant qu'argument.

Ainsi, pour indiquer que l'opération est réussie, nous appelons la resolvefonction et pour indiquer une opération infructueuse, nous appelons la rejectfonction.

Qu'est-ce que le Promise Chaining et pourquoi est-il utile ?

Le chaînage de promesses est une technique utilisée pour gérer les opérations asynchrones de manière plus organisée et lisible.

Dans le chaînage de promesses, nous pouvons attacher plusieurs .thengestionnaires dans lesquels le résultat du .thengestionnaire précédent est automatiquement transmis au .thengestionnaire suivant.

L'utilisation du chaînage de promesses permet d'éviter le problème de l'enfer des rappels que nous avons vu précédemment.

Le chaînage de promesses nous permet également d'écrire du code asynchrone de manière plus linéaire et séquentielle, ce qui est plus facile à lire et à comprendre.

De plus, lors de l'utilisation du chaînage de promesses, nous ne pouvons attacher qu'un seul .catchgestionnaire à la fin de tous les .thengestionnaires. Si l'une des promesses intermédiaires échoue, le dernier .catchgestionnaire sera automatiquement exécuté.

Nous n'avons donc pas besoin d'ajouter plusieurs .catchgestionnaires. Cela élimine la vérification des erreurs multiples comme nous l'avons fait précédemment dans l'exemple de l'enfer de rappel.

Comment fonctionne le chaînage des promesses

Nous pouvons ajouter plusieurs .thengestionnaires à une seule promesse comme ceci :

promise.then(function(result) {
 console.log('first .then handler');
 return result;
}).then(function(result) {
 console.log('second .then handler');
 console.log(result);
}).catch(function(error) {
 console.log(error);
});

Lorsque plusieurs .thengestionnaires sont ajoutés, la valeur de retour du .thengestionnaire précédent est automatiquement transmise au .thengestionnaire suivant.

promesse_chaining

Résultat de l'enchaînement des promesses

Comme vous pouvez le voir, l'ajout 4 + 5résout une promesse et nous obtenons cette somme dans le premier .thengestionnaire. Là, nous imprimons une instruction de journal et renvoyons cette somme au .thengestionnaire suivant.

Et à l'intérieur du .thengestionnaire suivant, nous ajoutons une déclaration de journal, puis nous imprimons le résultat que nous avons obtenu du .thengestionnaire précédent.

Cette façon d'ajouter plusieurs .thengestionnaires est connue sous le nom de chaînage de promesses.

Comment retarder l'exécution d'une promesse en JavaScript

Souvent, nous ne voulons pas que la promesse s'exécute immédiatement. Au contraire, nous voulons qu'il soit retardé jusqu'à ce qu'une opération soit terminée.

Pour ce faire, nous pouvons envelopper la promesse dans une fonction et renvoyer cette promesse à partir de cette fonction comme ceci :

function createPromise() {
 return new Promise(function(resolve, reject) {
  setTimeout(function() {
   const sum = 4 + 5;
   if(isNaN(sum)) {
     reject('Error while calculating sum.');
   } else {
    resolve(sum);
   }
  }, 2000);
 });
}

De cette façon, nous pouvons utiliser les paramètres de la fonction à l'intérieur de la promesse, ce qui rend la fonction vraiment dynamique.

function createPromise(a, b) {
 return new Promise(function(resolve, reject) {
  setTimeout(function() {
   const sum = a + b;
   if(isNaN(sum)) {
     reject('Error while calculating sum.');
   } else {
    resolve(sum);
   }
  }, 2000);
 });
}

createPromise(1,8)
 .then(function(output) {
  console.log(output); // 9
});

// OR

createPromise(10,24)
 .then(function(output) {
  console.log(output); // 34
});

fonction_générale

Résultat du retard d'exécution de la promesse

Remarque : lorsque nous créons une promesse, elle sera soit résolue, soit rejetée, mais pas les deux en même temps. Nous ne pouvons donc pas ajouter deux appels de fonction resolveou rejectdans la même promesse.

De plus, nous ne pouvons transmettre qu'une seule valeur à la fonction resolveou reject.

Si vous souhaitez transmettre plusieurs valeurs à une resolvefonction, transmettez-la en tant qu'objet comme ceci :

const promise = new Promise(function(resolve, reject) {
 setTimeout(function() {
  const sum = 4 + 5;
  resolve({
   a: 4,
   b: 5,
   sum
  });
 }, 2000);
});

promise.then(function(result) {
 console.log(result);
}).catch(function(error) {
 console.log(error);
});

object_resolve

Passer l'objet à la fonction de résolution pour renvoyer plusieurs valeurs

Comment utiliser les fonctions fléchées en JavaScript

Dans tous les exemples de code ci-dessus, nous avons utilisé la syntaxe de fonction ES5 standard lors de la création de promesses.

Mais il est courant d'utiliser la syntaxe de la fonction fléchée au lieu de la syntaxe de la fonction ES5.

Voyons donc d'abord ce qu'est une fonction fléchée et comment l'utiliser.

Que sont les fonctions fléchées ?

Avant ES6, il y avait deux manières principales de déclarer des fonctions.

1. Syntaxe de déclaration de fonction :

function add(a, b) {
 return a + b;
}

2. Syntaxe d'expression de fonction :

const add = function(a, b) {
 return a + b;
};

La principale différence visible entre la fonction régulière et la fonction fléchée est la syntaxe d'écriture de la fonction.

En utilisant la syntaxe de la fonction fléchée, nous pouvons écrire la fonction d'ajout ci-dessus comme ceci :

const add = (a, b) => {
 return a + b;
};

Vous ne verrez peut-être pas beaucoup de différence ici, à part la flèche. Mais si nous avons une seule ligne de code dans le corps de la fonction, nous pouvons simplifier la fonction fléchée ci-dessus comme ceci :

const add = (a, b) => a + b;

Ici, nous renvoyons implicitement le résultat de a + b, il n'y a donc pas besoin d'un returnmot-clé s'il n'y a qu'une seule instruction.

Ainsi, l'utilisation des fonctions fléchées rendra votre code beaucoup plus court.

En utilisant une fonction fléchée, nous pouvons écrire le code précédent comme indiqué ci-dessous :

const promise = new Promise((resolve, reject) => {
 setTimeout(() => {
  const sum = 4 + 5 + 'a';
  if(isNaN(sum)) {
    reject('Error while calculating sum.');
  } else {
    resolve(sum);
  }
 }, 2000);
});

promise.then((result) => {
 console.log(result);
});

Vous pouvez utiliser la syntaxe de fonction ES5 ou ES6 en fonction de vos préférences et de vos besoins.

Comment utiliser Async/Wait en JavaScript

Dans cette section, nous explorerons tout ce que vous devez savoir sur async/wait.

Async/wait donne aux développeurs une meilleure façon d'utiliser les promesses.

Pour utiliser async/wait, vous devez créer une fonction et ajouter le asyncmot-clé avant le nom de la fonction en utilisant la syntaxe de déclaration de fonction ES5 comme ceci :

async function someFunction() {
  // function body
}

ou en utilisant une syntaxe d'expression de fonction comme celle-ci :

const someFunction = async function () {
  // function body
};

ou en utilisant une fonction fléchée comme celle-ci :

const someFunction = async () => {
  // function body
};

Rappelez-vous toujours que lorsque vous ajoutez le mot-clé async à la fonction, il renvoie toujours une promesse.

Jetez un oeil au code ci-dessous:

const sayHello = async function () {
  return 'Hello';
};

sayHello();

Que pensez-vous que la sortie du code ci-dessus sera?

async_1

Résultat de l'appel de la fonction marquée comme asynchrone

La sortie est une promesse remplie avec la chaîne Hello.

Donc le code ci-dessous :

const sayHello = async function () {
  return 'Hello';
};

est le même que celui-ci :

const sayHello = function() {
 return new Promise((resolve, reject) => {
  resolve('Hello');
 });
}

qui est la même que celle-ci :

const sayHello = function () {
  return Promise.resolve('Hello');
};

Promise.resolve('Hello')est juste un moyen plus court de créer une promesse qui se résout en la chaîne Hello.

Donc, pour obtenir la chaîne réelle Hello, nous devons ajouter le .thengestionnaire comme ceci :

sayHello().then(function (result) {
  console.log(result); // Hello
});

async_hello

Obtenir le résultat de la fonction asynchrone à l'aide du gestionnaire .then

Maintenant, où utilisons-nous le awaitmot-clé ?

Il est utilisé à l'intérieur de la fonction qui est déclarée comme async. Ainsi, le awaitmot-clé ne doit être utilisé qu'à l'intérieur de la asyncfonction.

Vous obtiendrez une erreur si vous essayez de l'utiliser dans des fonctions non asynchrones.

Supposons que nous ayons une promesse qui renvoie le produit de deux nombres comme ceci :

function getProduct(a, b) {
  return new Promise(function (resolve, reject) {
    setTimeout(function () {
      resolve(a * b);
    }, 1000);
  });
}

et nous l'utilisons comme ceci:

getProduct(2, 4)
  .then(function (result) {
    getProduct(result, 2)
      .then(function (finalResult) {
        console.log('final_result', finalResult);
      })
      .catch(function (error) {
        console.log(error);
      });
  })
  .catch(function (error) {
    console.log(error);
  });

Dans le code ci-dessus, nous obtenons d'abord le produit de 2et 4. Ensuite, nous utilisons ce résultat pour le multiplier à 2nouveau, puis nous imprimons finalement le produit.

Si vous exécutez le code ci-dessus, vous verrez le résultat final comme 16 qui est 2 * 4 = 8 et 8 * 2 = 16.

async_product

Résultat de l'imbrication des gestionnaires de rappel .then

Le code ci-dessus de   .thenet .catchsemble assez compliqué et difficile à comprendre en un coup d'œil.

Donc, en utilisant async/wait, nous pouvons simplifier le code ci-dessus :

const printResult = async () => {
  try {
    const result = await getProduct(2, 4); // line 1
    const finalResult = await getProduct(result, 2); // line 2
    console.log('final_result', finalResult); // line 3
  } catch (error) {
    console.log(error);
  }
};

printResult();

Cela semble beaucoup plus propre et facile à comprendre.

Ici, pour utiliser le awaitmot-clé, nous déclarons une fonction avec le asyncmot-clé. Ensuite, pour obtenir le résultat de chaque promesse, nous ajoutons le awaitmot clé devant.

Notez également que nous avons ajouté try/catch dans la fonction. Vous devez toujours ajouter un bloc try autour du code utilisé awaitpour que le bloc catch soit exécuté si la promesse est rejetée.

Il y a une chose très importante dont vous devez vous souvenir : le code async/wait ci-dessus fonctionnera exactement de la même manière que lorsque nous l'utilisons .then- ainsi la awaitligne suivante (ligne 2) ne sera pas exécutée tant que l' awaitappel précédent (ligne 1) n'aura pas réussi.

Par conséquent, comme la getProductfonction prend 1 seconde à s'exécuter à cause de l'appel setTimeout, la ligne 2 devra attendre 1 seconde avant d'exécuter getProductà nouveau la fonction.

Mais il existe une exception à ce comportement, que vous pouvez consulter dans cet article .

De plus, s'il y a une erreur lors de l'exécution de la ligne 1 (à cause d'une erreur survenue dans la getProductfonction), le code suivant après la ligne 1 ne sera pas exécuté. Au lieu de cela, le bloc catch sera exécuté.

Maintenant, si vous comparez le chaînage du code de promesse et async/wait, vous verrez la différence.

// code using async/await

const printResult = async () => {
  try {
    const product = await getProduct(2, 4); // line 1
    const finalResult = await getProduct(product, 2); // line 2
    console.log('final_result', finalResult); // line 3
  } catch (error) {
    console.log(error);
  }
};

printResult();
// code using .then and .catch

getProduct(2, 4)
  .then(function (result) {
    getProduct(result, 2)
      .then(function (finalResult) {
        console.log('final_result', finalResult);
      })
      .catch(function (error) {
        console.log(error);
      });
  })
  .catch(function (error) {
    console.log(error);
  });

Comme vous pouvez le voir, le code utilisant async/wait est beaucoup plus propre et facile à comprendre par rapport au chaînage de promesses.

Au fur et à mesure que l'imbrication s'approfondit, le code utilisant le chaînage de promesses devient plus compliqué. Donc, async/wait fournit simplement un moyen d'écrire le même code mais avec une meilleure clarté.

L'utilisation de async/wait réduit également la nécessité d'ajouter plusieurs .catchgestionnaires pour gérer les erreurs.

Nous pouvons éviter l'imbrication dans le chaînage de promesses ci-dessus en écrivant le code précédent comme ceci :

getProduct(2, 4)
  .then(function (result) {
    return getProduct(result, 2);
  })
  .then(function (finalResult) {
    console.log('final_result', finalResult);
  })
  .catch(function (error) {
    console.log(error);
  });

Ici, à partir du premier .thengestionnaire, nous renvoyons le résultat de getProduct(result, 2).

Tout ce qui est renvoyé par le .thengestionnaire précédent sera transmis au .thengestionnaire suivant.

Au fur et à mesure que la getProductfonction renvoie une promesse, nous pouvons nous .theny attacher à nouveau et éviter d'avoir besoin d'un .catchgestionnaire imbriqué.

évitez_nested_handlers

utiliser le chaînage de promesses

Mais la syntaxe async/wait semble toujours plus propre et plus facile à comprendre que la syntaxe de chaînage de promesses.

Méthodes de promesse

Dans cette section, nous allons explorer les différentes méthodes fournies par l'API Promise.

Toutes ces méthodes sont utiles lorsque vous souhaitez exécuter plusieurs tâches asynchrones en même temps lorsque ces tâches ne sont pas dépendantes les unes des autres (ce qui fait gagner beaucoup de temps).

Parce que si vous exécutez chaque tâche l'une après l'autre, vous devez attendre la fin de la tâche précédente avant de pouvoir commencer la tâche suivante.

Et si les tâches ne sont pas liées les unes aux autres, il ne sert à rien d'attendre la fin de la tâche précédente avant d'exécuter la tâche suivante.

La Promise.allméthode

Cette méthode est utilisée pour exécuter plusieurs tâches asynchrones simultanément sans avoir à attendre la fin d'une autre tâche.

Supposons que nous ayons trois promesses et qu'elles soient toutes résolues avec succès :

const promise1 = new Promise((resolve, reject) => resolve('promise1 success'));
const promise2 = new Promise((resolve, reject) => resolve('promise2 success'));
const promise3 = new Promise((resolve, reject) => resolve('promise3 success'));

Maintenant, utilisons la Promise.allméthode.

Promise.alla besoin d'un tableau de promesses comme argument.

Promise.all([promise1, promise2, promise3])
  .then((result) => {
    console.log('resolved', result); // resolved ["promise1 success", "promise2 success", "promise3 success"]
  })
  .catch((error) => {
    console.log('rejected', error);
  });

promesse_tout

Comme toutes les promesses sont résolues, resultsera un tableau contenant les résultats des promesses résolues.

Maintenant, que se passe-t-il si l'une des promesses est rejetée ?

const promise1 = new Promise((resolve, reject) => resolve('promise1 success'));
const promise2 = new Promise((resolve, reject) => reject('promise2 failure'));
const promise3 = new Promise((resolve, reject) => resolve('promise3 success'));

Promise.all([promise1, promise2, promise3])
  .then((result) => {
    console.log('resolved', result);
  })
  .catch((error) => {
    console.log('rejected', error); // rejected promise2 failure
  });

promise_all_rejected

Dans le code ci-dessus, promise2 est rejetée donc le gestionnaire catch sera exécuté, et dans le cas de Promise.all:

  • Si l'une des promesses est rejetée, le errorcontiendra le message d'erreur de la promesse échouée (comme dans notre cas ci-dessus)
  • Si plusieurs promesses sont rejetées, le errorsera le message d'erreur de la première promesse échouée.

Remarque : même si la promesse intermédiaire est rejetée, l'exécution de toutes les promesses suivantes ne sera pas interrompue. Ils seront tous exécutés - mais seule la première valeur de promesse rejetée sera disponible dans le paramètre d'erreur du bloc catch.

La Promise.raceméthode

Considérez à nouveau les trois promesses résolues :

const promise1 = new Promise((resolve, reject) => resolve('promise1 success'));
const promise2 = new Promise((resolve, reject) => resolve('promise2 success'));
const promise3 = new Promise((resolve, reject) => resolve('promise3 success'));

Promise.race([promise1, promise2, promise3])
  .then((result) => {
    console.log('resolved', result); // resolved promise1 success
  })
  .catch((error) => {
    console.log('rejected', error);
  });

promesse_course_succès

Comme vous pouvez le voir ici, dès que la première promesse est résolue, la Promise.raceméthode renverra le résultat de cette promesse résolue.

Maintenant, jetez un oeil au code ci-dessous:

const promise1 = new Promise((resolve, reject) => reject('promise1 failure'));
const promise2 = new Promise((resolve, reject) => resolve('promise2 success'));
const promise3 = new Promise((resolve, reject) => resolve('promise3 success'));

Promise.race([promise1, promise2, promise3])
  .then((result) => {
    console.log('resolved', result);
  })
  .catch((error) => {
    console.log('rejected', error); // rejected promise1 failure
  });

promise_race_failed

Comme vous pouvez le voir ici, la première promesse elle-même est rejetée et le .catchgestionnaire sera donc exécuté.

Ainsi, lorsque nous utilisons la Promise.raceméthode, elle attendra que la première promesse soit résolue ou rejetée, puis :

  • Si la première promesse de la chaîne de promesses est résolue, le .thengestionnaire sera exécuté et le résultat sera le résultat de la première promesse résolue.
  • Si la première promesse de la chaîne de promesses est rejetée, le .catchgestionnaire sera exécuté et le résultat sera le résultat de la première promesse échouée.
  • Si plusieurs promesses sont rejetées, le .catchgestionnaire sera exécuté et le résultat sera le résultat de la première promesse échouée.

La Promise.allSettledméthode

Cette méthode est utile lorsque vous souhaitez connaître le résultat de chaque tâche même si elles sont rejetées.

Parce que dans Promise.allet Promise.race, nous n'obtenons que le résultat de la première promesse rejetée et il n'y a aucun moyen d'obtenir le résultat des autres promesses réussies ou échouées.

Ainsi, en utilisant Promise.allSettlednous pouvons obtenir le résultat de toutes les promesses, même si elles ont échoué.

Jetez un oeil au code ci-dessous:

const promise1 = new Promise((resolve, reject) => resolve('promise1 success'));
const promise2 = new Promise((resolve, reject) => resolve('promise2 success'));
const promise3 = new Promise((resolve, reject) => resolve('promise3 success'));

Promise.allSettled([promise1, promise2, promise3]).then((result) => {
  console.log('resolved', result);
});

/* output from `.then`:
resolved [
  {
    "status": "fulfilled",
    "value": "promise1 success"
  },
  {
    "status": "fulfilled",
    "value": "promise2 success"
  },
  {
    "status": "fulfilled",
    "value": "promise3 success"
  }
]
*/

promesse_allsettled_success

Comme vous pouvez le voir, la Promise.allSettledméthode attend que toutes les promesses soient résolues ou rejetées et resultcontiendra le résultat de chaque promesse.

const promise1 = new Promise((resolve, reject) => reject('promise1 failure'));
const promise2 = new Promise((resolve, reject) => resolve('promise2 success'));
const promise3 = new Promise((resolve, reject) => resolve('promise3 success'));

Promise.allSettled([promise1, promise2, promise3]).then((result) => {
  console.log('resolved', result);
});

/* output from `.then`:
resolved [
  {
    "status": "rejected",
    "reason": "promise1 failure"
  },
  {
    "status": "fulfilled",
    "value": "promise2 success"
  },
  {
    "status": "fulfilled",
    "value": "promise3 success"
  }
]
*/

promesse_allsettled_failure

Dans le cas ci-dessus, même si la première promesse est rejetée, nous obtenons le résultat de toutes les promesses à l'intérieur du .thengestionnaire.

const promise1 = new Promise((resolve, reject) => reject('promise1 failure'));
const promise2 = new Promise((resolve, reject) => reject('promise2 failure'));
const promise3 = new Promise((resolve, reject) => reject('promise3 failure'));

Promise.allSettled([promise1, promise2, promise3]).then((result) => {
  console.log('resolved', result);
});

/* output from `.then`:
 resolved [
  {
    "status": "rejected",
    "reason": "promise1 failure"
  },
  {
    "status": "rejected",
    "reason": "promise2 failure"
  },
  {
    "status": "rejected",
    "reason": "promise3 failure"
  }
] 
*/

promise_allsettled_multiple_failure

Ici, même si toutes les promesses sont rejetées, le .thengestionnaire sera toujours exécuté et nous obtenons le résultat de chaque promesse.

Merci d'avoir lu!

C'est tout pour ce tutoriel. J'espère que vous en avez beaucoup appris.

Source : https://www.freecodecamp.org

#javascript

1.80 GEEK