Azur Web
Henrique Rodrigues
Développeur Web

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éussit et soit terminée avant d'exécuter un autre bout de code.

Bien entendu les promesses ne seront t'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é 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é et le message "Vous n'avez pas salué" aurait apparu.

Chainage des promesses en Javascript

Le chainage des promesses en Javascript permettent 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.

  • promesse1 : 3000 millisecondes (3 secondes)
  • promesse2 : 2000 millisecondes (2 secondes)
  • promesse3 : 1000 millisecondes (1 secondes)
  • promesse4 : 500 millisecondes (0,5 secondes)

Utiliser plusieurs promesses sous forme d'une chaîne

Pour utiliser les quatres promesses préalablement déclarer 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);

  });

Le 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 promesses.

Opérations asynchrones en parallèle

Quelque-fois nous avons besoin d'utiliser plusieurs promesses en Javascript mais sans le chainage de celles-ci. Ce qui est possible de faire dans ce cas là c'est de lancer des opérations asynchrones en parallèles grâce au promesses et ensuite attendre que toutes les opérations soient terminées pour ensuite utiliser les résulats.

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

Promise.all([promesse1(), promesse2(), promesse3(), promesse4()])
  .then(function (res1, res2, res3, res4) {

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

  })
  .catch(function (resErreur) {

    console.log(resErreur);

  });

Décorticons 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 y place comme d'habitude une fonction anonyme avec des paramètres qui correspondant aux résultats des promesses indiquées dans les paramètres de "all".

Que ce passe t'il?

Toutes les promesses sont exécutées chacunes de leurs cotés. Cela veut dire par exemple que la deuxième promesse commence son activté 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 chacunes de leurs cotés, 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èles sera plus adéquat car plus rapide dans son exécution.

Sources

MDN web docs: Utiliser les promesses

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

Email
Cela ne fontionne pas.