Node.js Promise

Promise est l'un des concepts fondamentaux pour la gestion des opérations asynchrones dans Node.js.

Promise offre une manière plus élégante de gérer le code asynchrone, évitant le problème traditionnel de l'enfer des callbacks.

Cet article détaillera le concept, l'utilisation et les modèles courants de Promise.


Qu'est-ce qu'une Promise ?

Une Promise est un objet représentant l'achèvement ou l'échec éventuel d'une opération asynchrone. Elle a trois états :

  1. Pending (en attente): État initial, ni en réussite ni en échec
  2. Fulfilled (réussi): L'opération s'est terminée avec succès
  3. Rejected (échoué): L'opération a échoué

Une fois que l'état d'une Promise change (de pending à fulfilled ou rejected), il ne changera plus.


Création d'une Promise

Dans Node.js, vous pouvez utiliser lePromiseconstructeur pour créer un nouvel objet Promise :

Exemple

const myPromise = new Promise((resolve, reject) => {
  // Opération asynchrone
  const success = true; // Supposons que ceci soit le résultat de l'opération asynchrone
 
  if (success) {
    resolve('Operation succeeded!'); // L'état devient résolu
  } else {
    reject('Operation failed!'); // L'état devient rejeté
  }
});

Utilisation de Promise

Promise fournit la.then()et.catch()méthode pour gérer les cas de succès et d'échec :

Exemple

myPromise
  .then((result) => {
    console.log(result); // Sortie : "Operation succeeded!"
  })
  .catch((error) => {
    console.error(error); // Sortie : "Operation failed!"
  });

Chaînage de promesses

La puissance de Promise réside dans sa capacité à enchaîner plusieurs opérations asynchrones :

Exemple

function asyncOperation1() {
  return new Promise((resolve) => {
    setTimeout(() => resolve('Première étape terminée'), 1000);
  });
}

function asyncOperation2(data) {
  return new Promise((resolve) => {
    setTimeout(() => resolve(`${data},Deuxième étape terminée`), 1000);
  });
}

asyncOperation1()
  .then((result) => asyncOperation2(result))
  .then((finalResult) => {
    console.log(finalResult); // Sortie : "Première étape terminée, Deuxième étape terminée"
  })
  .catch((error) => {
    console.error('Erreur dans la chaîne :', error);
  });

Méthodes statiques de Promise

Promise fournit quelques méthodes statiques utiles :

Promise.all()

Attend que toutes les Promesses soient terminées, ou qu'une seule Promesse échoue :

Exemple

const promise1 = Promise.resolve('premier');
const promise2 = Promise.resolve('second');

Promise.all([promise1, promise2])
  .then((results) => {
    console.log(results); // Sortie : ['first', 'second']
  });

Promise.race()

Renvoie la Promise qui se règle en premier (accomplie ou rejetée) :

Exemple

const promise1 = new Promise((resolve) => setTimeout(resolve, 500, 'first'));
const promise2 = new Promise((resolve) => setTimeout(resolve, 100, 'second'));

Promise.race([promise1, promise2])
  .then((result) => {
    console.log(result); // Sortie : "second"
  });

Gestion des erreurs

La gestion des erreurs de Promise peut se faire via.catch()ou.then()le second paramètre de .then :

Exemple

someAsyncFunction()
  .puis(
    (result) => { /* Gérer le succès */ },
    (error) => { /* Gérer l'échec */ }
  );

// Ou
someAsyncFunction()
  .then((result) => { /* Gérer le succès */ })
  .catch((error) => { /* Gérer toutes les erreurs */ });

Syntaxe async/await

ES2017 a introduit la syntaxe async/await, rendant l'utilisation de Promise plus intuitive :

Exemple

async function runOperations() {
  try {
    const result1 = await asyncOperation1();
    const result2 = await asyncOperation2(result1);
    console.log(result2);
  } catch (error) {
    console.error(error);
  }
}

runOperations();

Bonnes pratiques

  1. Toujours gérer les erreurs: Ne les ignorez pas.catch()ou try-catch
  2. Éviter l'imbrication: Utiliser le chaînage ou async/await pour garder le code plat
  3. Nommer les Promises: Donner des noms significatifs aux variables Promise
  4. Retourner des Promises: Retourner des Promises à partir des fonctions pour permettre le chaînage
Autres extensions