Promesses

PROMESSES ?

Une promesses est un objet repésentrant le résultat futur d’une action effectuée de manière asynchrone: c’est donc un objet représentant une valeur qui n’est pas encore disponible.
Cela permet de remplacer les callbacks pour gérer les succès et erreurs d’une manière plus élégante.

    // callback
    getInfo(login, function(user) {
        getCreditential(user, function (token) {
            updateProfile(token);
        });
    });

    // ES6 Promises
    getInfo(login)
        .then( user, () =>  getCreditential(user) )
        .then( token, () => updateProfile(token) );


Une promesse à 2 méthodes: then et catch

then permet récupérer le résultat d’une promesse et de chainer les promesses entre elles.

Cette méthode a deux arguments:

  • un callback de succès et
  • callback d’erreur.

Une promesse a trois états:

  • pending : en cours, promesse non réalisée, la valeur n’est pas encore arrivée
  • fulfilled : résolue, promesse réalisée avec succès, on peut l’utiliser
  • rejected : rejetée, promesse échouée, on peut y réagir

Si la promesse est re?alise?e le callback de succès est invoque?, avec le re?sultat en argument.
Si la promesse est rejete?e le callback d’erreur est invoque?, avec la valeur rejete?e ou une erreur en argument.

catch permet de récupérer l’erreur d’une ou plusieurs promesses.

COMMENT CRÉER UNE PROMESSE

Avec la classe Promise dont le constructeur attend 2 arguments : resolve et reject

    // Création de la promesse
    const getInfo = (success) => {
        return new Promise(function (resolve, reject) {
            // ... code qui fait plein de chose asynchrone comme récupérer des résultats depuis un serveur et retournée une réponse
            if (success) { // promesse terminée
                resolve(success);
            } else {
                reject('No Info');
            }
        });
    };

    // utilisation
    getInfo(success)
        .then(
            function(response){ // si succès
                console.log(response);
            },
            function(error){ // si erreur
                console.log(error);
            },
        );

    // si le callback de succès retourne une promesse aussi pas de problème: 

    getInfo(login)
        .then( response, () =>  getCreditential(response) );


On peut définir une erreur par promesse, mais on peut aussi aussi définir la gestion des erreurs de facon globale.


    getInfo(login)
        .then( user, () =>  getCreditential(user) )
        .then( token, () => updateProfile(token) )
        .catch( (error) => console.log(error) ); // sera appellé si getCreditential() ou updateProfile() sont rejetés

Les promesses sont une fonctionnalité déjà disponible avec l’API Fetch (+ un polyfill pour être compatible tout navigateur)

    const fetchPost = fetch('https://jsonplaceholder.typicode.com/posts/1');

    fetchPost
        .then(fetchResult => fetchResult.text())
        .then(postResult => {  // Quand parsing est terminé récupération du contenu
            console.log(`Résultat : ${postResult}`)
        })
        .catch(error => { // si erreur
            console.log("Une erreur a eu lieu", error)
        });


Pour Information: Il n’y a pas de finally (angular) ou always (jquery) (pour l’instant prévu pour ES8) mais une méthode pour y arriver serait :

myES6Promise.then(() => console.log('Resolved'))
            .catch(() => console.log('Failed'))
            .then(() => console.log('Always run this'));
 

ou extend le prototype mais ce n’est pas recommandé

Promise.prototype.finally = function(cb) {
    const res = () => this;
    const fin = () => Promise.resolve(cb()).then(res);
    return this.then(fin, fin);
};
 

ou avec async et await (ES7)

async function(somePromise) {
  try {
    await somePromise();
  } finally {
    // always run this-- even if `somePromise` threw something
  }
}

Et en es7, Es8 les mots clés async et await permettront de faire de l’asynchrone encore plus facilement