ES6 : quelques nouveautés de la prochaine version de JavaScript – Part III

Cet article est la suite d’une série d’articles sur ES6 :

Avant de commencer, une petite information en terme de nommage, ES6 a été renommé en ES2015.

Promise

Définissons tout d’abord ce qu’est une promesse :
Une promesse représente l’éventuel résultat d’une opération asynchrone

La notion de promise (promesse en français) n’est pas nouvelle et existe dans différentes librairies sous différentes formes comme :

Les Promise seront inclus de manière native dans ES6.

Les promise permettent de gérer plus facilement les méthodes asynchrones et d’éviter un code difficile à lire et maintenable si on utilise des callback. En effet on arrive facilement à avoir du code comme cela :

step1(function (value1) {
    step2(function (value2) {
        step3(function (value3) {
            step4(function (value4) {
                step5(function (value5) {
                    step6(function (value6) {
                        // Do something with value6
                    });
                });
            });
        });
    });
});

C’est ce qu’on appelle pyramid of doom ou callback hell.

Un nouvel objet Promise est introduit dans ES6. Le constructeur prend en paramètre une fonction avec 2 fonctions en paramètre : resolved et reject. La fonction resolve est à appeler si il n’y a pas eu d’erreur avec les valeurs de retour. Elle permet d’indiquer que la promise est résolue permettant la suite des actions. La fonction reject est à appeler si une erreur est survenue.

Création d’une Promise

    var promise = new Promise(
        function (resolve, reject) { // (A)
            ...
            if (...) {
                resolve(value); // success
            } else {
                reject(reason); // failure
            }
        });

Une fois notre promise définie, nous allons pouvoir définir un handler sur cette promise afin de réaliser des actions sur la future valeur. L’enchaînement des actions se fait via la méthode then. Cette fonction prend en paramètre 2 fonctions: la 1ere pour le succès (resolve) et la deuxième lors d’une erreur (reject). Les erreurs peuvent être également gérés via la méthode catch.

Utilisation d’une promise

 httpGet('http://myServer.com/file.txt')
    .then(
        function (value) { //Success
            console.log('Contents: ' + value);
        },
        function (reason) { //Error
            console.error('An error occurred', reason);
        });

L’avantage des promises est qu’on peut facilement les chaîner, ou les composer.

Fetch, la nouvelle API pour faire des appels Ajax utilise les promises. (un article pour aller plus loin)

Il existe des polyfills afin de pouvoir les utiliser dès maintenant :

Quelques liens sur le sujet :

Destructuring

Le destructuring permet d’initialiser des variables en les extrayant à partir d’objet existant.

//Array : on extrait 3 variables m, d et y à partir d'un tableau
var [m, d, y] = [12, 21, 1981]; 

//object : on extrait les propriétés d'un objet
//Ici on définit une fonction qui extrait la liste des classe CSS d'un élément
var listOfCLass = function ({ classList } ) {
    Array.from(classList).forEach( (item) => console.log(item))
};
listOfCLass(document.body);

Une autre utilisation avec un module quand on ne veut importer qu’une partie d’un module. (cf chapitre module dans la partie II).

Quelques liens :

ES7

La future version d’EcmaScript est déjà en préparation et je vais parler de 2 des nouveautés qui sont à mes yeux les plus intéressantes.

Object.observe

Object.observe() est une nouvelle API qui permet de s’abonner aux changements effectués sur un objet. A chaque modification sur l’objet, un événement sera lancé contenant la liste des changements (ajout d’une propriété, modification d’une valeur, suppression d’une propriété) sur l’objet.

Voici un exemple tirée de la documentation de Object.observe sur MDN :

var obj = {
  foo: 0,
  bar: 1
};

Object.observe(obj, function(changes) {
  console.log(changes);
});

obj.baz = 2;
// [{name: 'baz', object: <obj>, type: 'add'}]

obj.foo = 'hello';
// [{name: 'foo', object: <obj>, type: 'update', oldValue: 0}]

delete obj.baz;
// [{name: 'baz', object: <obj>, type: 'delete', oldValue: 2}]

Cela permet notamment de facilement mettre en place du data-binding (Angular 2 l’utilise afin d’améliorer les performances et éviter le « dirty checking »).

Quelques liens sur le sujet :

Async/Await

ES6 simplifie, via l’introduction des promesses, grandement la gestion de code asynchrone. Async va encore plus loin afin de faciliter la lecture et la compréhension.
ES7 introduit 2 nouveaux mots clés : async et await.

async permet de définir une fonction comme étant asynchrone alors que await permet d’indiquer que l’on souhaite bloquer l’exécution du code jusqu’au retour de la fonction.

Voici un exemple d’utilisation :

async function getUserName() {
    return 'royto';
}

async function displayLogoutMessage() {
    var user = await getUserName();
    alert(`GoodBye ${user} !`);
}

Pour ceux qui viennent du monde .NET cette syntaxe ne devrait pas les surprendre 🙂

Quelques liens :

Liens sur ES6 / ES2015

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *