< Retour

Fonctionnement des promesses en JavaScript

JavaScript

Qu’est-ce qu’une promesse ?

La promesse en JavaScript permet d’attendre qu’une opération asynchrone ait réussi et soit terminée avant d’exécuter un autre bout de code.

Bien entendu, les promesses ne seront utiles que dans le cas où notre opération est longue (et nous ne souhaitons pas qu’elle bloque le reste du code) ou lors d’un envoi d’une requête à un serveur qui nous enverra ensuite une réponse que nous utiliserons.

Déclaration d’une promesse

Pour créer une promesse, il faut utiliser l’objet "Promise".

On déclare une fonction. Et dans celle-ci, on insère un "return" d’une nouvelle instance de l’objet "Promise".

var direSalutation = function () {

  return new Promise( function(resolve, reject) {

  })

}

La promesse est créée, mais elle n’est pas encore exploitable.

Comme vous pouvez l’observer, la promesse contient une autre fonction anonyme avec deux paramètres appelés communément "resolve" et "reject". Bien que ce ne soit pas conseillé, vous avez la possibilité si vous le souhaitez de changer les noms de ces paramètres.

Le paramètre "resolve" correspond à une fonction qui sera exécutée si nous considérons que l’opération dans la promesse s’est bien déroulée. Le paramètre "reject" est également une fonction, mais celle-ci est utilisée pour indiquer à l’utilisateur une erreur.

Pour illustrer tout cela, nous allons utiliser la fonction "direSalutation", insérer un paramètre et utiliser les paramètres "resolve" et "reject" de la promesse.

var direSalutation = function (salutation) {

  return new Promise( function(resolve, reject) {

      if(salutation === 'bonjour') {

        resolve('Vous avez dit ' + salutation);

      } else {

        reject('Vous n\'avez pas saluez');

      }


  })

}

Lorsque cette fonction JavaScript (qui contient une promesse) est exécutée si le paramètre est égale à "bonjour" alors "resolve" est exécutée sinon "reject" est exécutée.

Nous allons maintenant voir comment l’utiliser.

Utiliser une promesse

Dans cette partie nous utiliserons une promesse créée dans la précédente partie.

direSalutation()
  .then(function() {


  })
  .catch(function() {



  });

La fonction anonyme dans la méthode "then" correspond à la fonction "resolve" de la promesse et la méthode "catch" à la fonction "reject". Ainsi si l’on insère un paramètre dans la fonction de la méthode "then" on récupère celle qui est dans la fonction resolve.

direSalutation('bonjour')
  .then(function(res) {

    console.log(res);


  })
  .catch(function(resErreur) {

   console.log(resErreur);

  });

// "Vous avez dit bonjour"

Le résultat du code est "Vous avez dit bonjour". Si on avait changé le paramètre de la fonction "direSalutation" par autre chose que "bonjour", la fonction "reject" de la promesse aurait été exécutée et le message "Vous n’avez pas salué" aurait apparu.

Chainage des promesses en JavaScript

Le chainage des promesses en JavaScript permet d’attendre le résultat d’une promesse pour ensuite l’utiliser dans une autre promesse et ainsi de suite.

Pour bien comprendre ce principe, nous allons utiliser quatre promesses relativement identiques. Pour simuler une opération asynchrone, nous allons utiliser la méthode "setTimeout" qui permet d’exécuter un code au bout d’un nombre de millisecondes.

// Première promesse
var promesse1 = function () {

  return new Promise( function(resolve, reject) {

      setTimeout(function() {

        resolve('Promesse1');

      }, 3000);


  })

}

// Deuxième promesse
var promesse2 = function () {

  return new Promise( function(resolve, reject) {

      setTimeout(function() {

        resolve('Promesse2');

      }, 2000);


  })

}

// Troisième promesse
var promesse3 = function () {

  return new Promise( function(resolve, reject) {

      setTimeout(function() {

        resolve('Promesse3');

      }, 1000);


  })

}

// Quatrième promesse
var promesse4 = function () {

  return new Promise( function(resolve, reject) {

      setTimeout(function() {

        resolve('Promesse4');

      }, 500);


  })

}

Nous avons ici quatre promesses qui exécutent la fonction "resolve" au bout de x millisecondes.

Utiliser plusieurs promesses sous forme d’une chaîne

Pour utiliser les quatre promesses préalablement déclarées, nous allons utiliser plusieurs méthodes "then".

promesse1()
  .then(function(res) {

    console.log(res)
    return promesse2();


  })
  .then(function(res) {

    console.log(res)
    return promesse3();


  })

  .then(function(res) {

    console.log(res)
    return promesse4();


  })
  .then(function(res) {

    console.log(res);


  })
  .catch(function(resErreur) {

   console.log(resErreur);

  });

La première promesse est exécutée. Au bout de 3 secondes, la première méthode "then" est appelée. Cette méthode contient un "return" de la deuxième promesse qui est alors exécutée. Au bout de 2 secondes, la deuxième méthode "then" est exécutée. Et ainsi de suite, jusqu’à la quatrième promesse.

Opérations asynchrones en parallèle

Quelquefois nous avons besoin d’utiliser plusieurs promesses en JavaScript, mais sans le chainage de celles-ci. Ce qu’il est possible de faire dans ce cas là c’est de lancer des opérations asynchrones en parallèle grâce aux promesses et ensuite attendre que toutes les opérations soient terminées pour ensuite utiliser les résultats.

Pour cela nous allons utiliser la méthode "all" de l’objet "Promise".

Promise.all([promesse1(), promesse2(), promesse3(), promesse4()])
  .then(function (res) {

    console.log(res[0]); // Résultat de la fonction promesse1
    console.log(res[1]); // Résultat de la fonction promesse2
    // ...

    console.log('Toutes les promesses ont été exécutées');

  })
  .catch(function (resErreur) {

    console.log(resErreur);

  });

Décortiquons ce code.

Comme il a été dit plus haut, il faut utiliser la méthode "all" de l’objet "Promise". Dans les paramètres il faut exécuter les fonctions qui contiennent les promesses (dans notre cas il y en a quatre).

Dans la méthode "then", on place comme d’habitude une fonction anonyme avec un paramètre (sous forme d’un tableau de taille identique aux nombres de fonctions) qui correspond aux résultats des promesses indiquées dans les paramètres de "all" sous fo.

Que se passe-t-il ?

Toutes les promesses sont exécutées chacune de leur côté. Cela veut dire par exemple que la deuxième promesse commence son activité en même temps que la première (elle n’attend donc pas que la première soit terminée comme dans le cas du chainage de promesses). Lorsque les promesses sont toutes terminées chacune de leur côté, le code dans "then" est exécuté.

Chainage ou exécution en parallèle ?

Maintenant posons-nous la question suivante: lorsque nous avons besoin d’exécuter plusieurs promesses en JavaScript, devons-nous utiliser le chainage ou l’exécution en parallèle ?

Tout dépend de notre objectif. Si les promesses ont absolument besoin des résultats d’autres promesses, il faut utiliser la méthode du chainage. Sinon la méthode qui permet de mener des opérations en parallèle sera plus adéquate, car plus rapide dans son exécution.

Sources

MDN web docs: Utiliser les promesses

Vidéo DevTheory: Comment fonctionne les Promesses en JavaScript ?

Je veux parler avec Henrique

Me parler :

Si vous souhaitez me contacter, vous pouvez accéder à la page d'accueil.

Attendre
Patientez ...