Le Tutoriel de ECMAScript Promise, Async Await

View more Tutorials:

1- Qu'est-ce que Promise ?

En programmation informatique, vous travaillez souvent avec des fonctions (function) et lorsque vous appelez une fonction, vous obtenez presque immédiatement le résultat renvoyé.
function sum(a, b)  {
  return a + b;
}

// Call function:
let result = sum(10, 5);

console.log(result);
 
Supposons que vous créiez une fonction appelée downloadFile(url) pour télécharger un fichier depuis Internet
Le téléchargement d'un fichier volumineux peut prendre plusieurs minutes ou plus. En appelant la fonction downloadFile(url) de façon synchrone, elle gèlera toutes les actions de l'utilisateur jusqu'à ce qu'elle soit terminée. Ainsi, pendant le téléchargement du fichier, l'utilisateur ne peut pas manipuler l'application. 
Par conséquent, vous ne pouvez pas vous attendre à une fonction comme suit :
// Call download:

var myfile = downloadFile("http://example.com/file.mp3");

Promise?

  • La réponse est que cette fonction devrait renvoyer une Promise (promesse) au lieu d'un fichier.
Imaginons que votre belle petite amie vous dise : "S'il vous plaît, épousez-moi !" D'accord, bien sûr, mais vous ne pouvez pas le faire immédiatement parce que vous avez besoin de plus de temps pour vous préparer mais elle attend votre réponse et il est préférable de lui faire une promesse puis immédiatement les deux sont heureux.

Promise State?

Une  Promise contient 3 états  :
État Description
Pending La Promise est en cours, vous ne pouvez pas savoir si elle va réussir ou échouer. Par exemple, le fichier est en cours de téléchargement.
Fulfilled La mission de la Promise a été accomplie. Par exemple, le fichier a été téléchargé avec succès.
Rejected La mission de la Promise a échoué. Par exemple, il y a eu une erreur pendant le processus de téléchargement.
La syntaxe de la création d'un objet  Promise :
new Promise (
      function (resolve, reject) {
           // Codes
      }
);
Exemple :
// [ECMAScript 5 Syntax]

var isNetworkOK = true;

// A Promise
var willIGetAFile = new Promise (
    function (resolve, reject) {

        if (isNetworkOK) {
            console.log("Complete the download process!"); // ***
            var file = {
                fileName: 'file.mp3',
                fileContent: '...',
                fileSize: '3 MB'
            };
            resolve(file); // fulfilled
        } else {
            console.log("File download process failed!"); // ***
            var error = new Error('There is a problem with the network.');
            reject(error); // reject
        }

    }
);
Votre fonction  downloadFile(url) va renvoyer un objet  Promise, comme ci-dessous :
// [ECMAScript 5 Syntax]

var isNetworkOK = true;

// This function return a Promise
function downloadFile(url)  {
    console.log("Start downloading file ..."); // ***

    // A Promise
    var willIGetAFile = new Promise (
        function (resolve, reject) {

            if (isNetworkOK) {
                console.log("Complete the download process!"); // ***
                var file = {
                    fileName: 'file.mp3',
                    fileContent: '...',
                    fileSize: '3 MB'
                };
                resolve(file); // fulfilled
            } else {
                console.log("File download process failed!"); // ***
                var error = new Error('There is a problem with the network.');
                reject(error); // reject
            }

        }
    );

    return willIGetAFile; // Return a Promise.
}

2- Utiliser Promise

Dans la partie ci-dessus, nous avons la fonction downloadFile(url), qui renvoie un objet Promise. Nous allons maintenant apprendre comment utiliser cette fonction. 
// Call downloadFile(..) function:
// Returns a Promise object:
var willIGetAFile = downloadFile("http://example.com/file.mp3");


willIGetAFile
        .then(function (fulfilled) {
            // Get a File
            // Output: {fileName: 'file.mp3', fileContent: '...', fileSize: '3 MB'}
            console.log(fulfilled);
        })
        .catch(function (error) {
             // Network Error!
             // Output: There is a problem with the network.
             console.log(error.message);
        });
OK, voici le code complet de cet exemple :
promise-example.js
// [ECMAScript 5 Syntax]

var isNetworkOK = true;

// This function return a Promise
function downloadFile(url)  {
    console.log("Start downloading file ..."); // ***

    // A Promise
    var willIGetAFile = new Promise (
        function (resolve, reject) {

            if (isNetworkOK) {
                console.log("Complete the download process!"); // ***
                var file = {
                    fileName: 'file.mp3',
                    fileContent: '...',
                    fileSize: '3 MB'
                };
                resolve(file); // fulfilled
            } else {
                console.log("File download process failed!"); // ***
                var error = new Error('There is a problem with the network.');
                reject(error); // reject
            }

        }
    );

    return willIGetAFile; // Return a Promise.
}

// Call downloadFile(..) function:
// Returns a Promise object:
var willIGetAFile = downloadFile("http://example.com/file.mp3");


willIGetAFile
        .then(function (fulfilled) {
            // Get a File
            // Output: {fileName: 'file.mp3', fileContent: '...', fileSize: '3 MB'}
            console.log(fulfilled);
        })
        .catch(function (error) {
             // Network Error!
             // Output: There is a problem with the network.
             console.log(error.message);
        });
 
Si  isNetworkOK = true, lors de l'exécution de l'exemple, vous recevez le résultat :
Si  isNetworkOK = false, lors de l'exécution de l'exemple, vous recevez le résultat :

3- Chaining Promise

Chaining Promise (Chaîne de Promesse) est un ensemble de Promise consécutives qui sont rassemblées.
Imaginez que vous devez effectuer les 2 actions suivantes : appeler la fonction downloadFile(url) pour télécharger un fichier depuis Internet, puis appeler la fonction openFile(file) pour ouvrir le fichier que vous venez de télécharger.
Le téléchargement d'un fichier à partir d' Internet prend un certain temps. La fonction downloadFile(url) est conçue pour vous envoyer une promesse ( Promise). Vous ne pouvez ouvrir des fichiers que si le téléchargement est réussi. Par conséquent, vous devriez également concevoir la fonction openFile(file) pour retourner une promesse ( Promise).
Écrivez la fonction openFile(file) pour renvoyer un objet  Promise.
function openFile(file) {
    console.log("Start opening file ..."); // ***

    var willFileOpen = new Promise(
        function (resolve, reject) {
             var message = "File " + file.fileName + " opened!"
             resolve(message);
        }
    );

    return willFileOpen; // Return a Promise.
}
Au lieu de créer un objet Promise via l'opérateur new, vous pouvez utiliser des méthodes Promise.resolve(value) ou Promise.reject(error) statiques.  Ces deux méthodes renvoient un objet Promise.   
Vous pouvez écrire une fonction  openFile(file) au-dessus plus concise :
// Shorter:

function openFile(file) {
    console.log("Start opening file ..."); // ***
    
    var message = "File " + file.fileName + " opened!"

    // Create a Promise
    var willFileOpen = Promise.resolve(message);
    return willFileOpen;
}

 
Appelez la fonction  downloadFile(url) et  openFile(file) à la manière  Promise :
console.log("Start app.."); // ***

// Call downloadFile(..) function:
// Returns a Promise object:
var willIGetAFile = downloadFile("http://example.com/file.mp3");


willIGetAFile
        .then(openFile) // Chain it!
        .then(function (fulfilled) { // If successful fileOpen.
            // Get a message after file opened!
            // Output: File file.mp3 opened!
            console.log(fulfilled);
        })
        .catch(function (error) {
             // Network Error!
             // Output: There is a problem with the network.
             console.log(error.message);
        });


console.log("End app.."); // ***
Voir le code complet de l'exemple :
chaining-promise-example.js
// [ECMAScript 5 Syntax]

var isNetworkOK = true;

// This function return a Promise
function downloadFile(url)  {
    console.log("Start downloading file ..."); // ***

    // A Promise
    var willIGetAFile = new Promise (
        function (resolve, reject) {

            if (isNetworkOK) {
                console.log("Complete the download process!"); // ***
                var file = {
                    fileName: 'file.mp3',
                    fileContent: '...',
                    fileSize: '3 MB'
                };
                resolve(file); // fulfilled
            } else {
                console.log("File download process failed!"); // ***
                var error = new Error('There is a problem with the network.');
                reject(error); // reject
            }

        }
    );

    return willIGetAFile; // Return a Promise.
}

function openFile(file) {
    console.log("Start opening file ..."); // ***

    var willFileOpen = new Promise(
        function (resolve, reject) {
             var message = "File " + file.fileName + " opened!"
             resolve(message);
        }
    );

    return willFileOpen; // Return a Promise.
}

// Call downloadFile(..) function:
// Returns a Promise object:
var willIGetAFile = downloadFile("http://example.com/file.mp3");


willIGetAFile
        .then(openFile) // Chain it!
        .then(function (fulfilled) { // If successful fileOpen.
            // Get a message after file opened!
            // Output: File file.mp3 opened!
            console.log(fulfilled);
        })
        .catch(function (error) {
             // Network Error!
             // Output: There is a problem with the network.
             console.log(error.message);
        });
 
Exécutez l'exemple et recevez le résultat :

4- Promise est asynchrone

Promise st asynchrone (Asynchronous). Cela signifie que lorsque vous appelez une fonction Promise (Fonction renvoie 1 Promise). Il ne gèlera pas votre demande pendant la durée de l'exécution de la Promise.
Pour clarifier cette question, nous corrigeons un peu l'exemple ci-dessus. Utilisez la fonction setTimeout() pour simuler la prise de temps en téléchargeant un fichier.
chaining-promise-example-2.js
// [ECMAScript 5 Syntax]

var isNetworkOK = true;

// This function return a Promise
function downloadFile(url)  {
    console.log("Start downloading file ..."); // ***

    // A Promise
    var willIGetAFile = new Promise (
        function (resolve, reject) {

            if (isNetworkOK) {
                setTimeout( function() {
                    console.log("Complete the download process!"); // ***
                    var file = {
                        fileName: 'file.mp3',
                        fileContent: '...',
                        fileSize: '3 MB'
                    };
                    resolve(file); // fulfilled
                }, 5 * 1000); // 5 Seconds
            } else {
                var error = new Error('There is a problem with the network.');
                reject(error); // reject
            }

        }
    );

    return willIGetAFile; // Return a Promise.
}


function openFile(file) {
    console.log("Start opening file ..."); // ***

    var willFileOpen = new Promise(
        function (resolve, reject) {
             var message = "File " + file.fileName + " opened!"
             resolve(message);
        }
    );

    return willFileOpen; // Return a Promise.
}

console.log("Start app.."); // ***

// Call downloadFile(..) function:
// Returns a Promise object:
var willIGetAFile = downloadFile("http://example.com/file.mp3");


willIGetAFile
        .then(openFile) // Chain it!
        .then(function (fulfilled) { // If successful fileOpen.
            // Get a message after file opened!
            // Output: File file.mp3 opened!
            console.log(fulfilled);
        })
        .catch(function (error) {
             // Network Error!
             // Output: There is a problem with the network.
             console.log(error.message);
        });

console.log("End app.."); // ***
 
 
Le résultat que vous obtenez en exécutant l'exemple ci-dessus :
Veuillez faire attention à l'ordre dans lequel les messages sont imprimés sur l'écran de Console :
Start app..
Start downloading file ...
End app..
Complete the download process!
Start opening file ...
File file.mp3 opened!

5- Promise en ES6

ECMAScript-6 est inclus une syntaxe Fonctions fléchées (Narrow Function), par conséquent, vous pouvez réécrire l'exemple ci-dessus par la syntaxe ES6 :
chaining-promise-es6-example.js
// [ECMAScript 6 Syntax]

var isNetworkOK = true;

// This function return a Promise
downloadFile = function(url)  {
    console.log("Start downloading file ..."); // ***

    // A Promise
    var willIGetAFile = new Promise (
       (resolve, reject) => {

           if (isNetworkOK) {
               setTimeout( function() {
                   console.log("Complete the download process!"); // ***
                   var file = {
                       fileName: 'file.mp3',
                       fileContent: '...',
                       fileSize: '3 MB'
                   };
                   resolve(file); // fulfilled
               }, 5 * 1000); // 5 Seconds
           } else {
               var error = new Error('There is a problem with the network.');
               reject(error); // reject
           }
        }
    );

    return willIGetAFile; // Return a Promise.
}

openFile = function (file) {
    console.log("Start opening file ..."); // ***

    var willFileOpen = new Promise(
       (resolve, reject) => {
             var message = "File " + file.fileName + " opened!"
             resolve(message);
        }
    );

    return willFileOpen; // Return a Promise.
}


console.log("Start app.."); // ***

// Call downloadFile(..) function:
// Returns a Promise object:
var willIGetAFile = downloadFile("http://example.com/file.mp3");


willIGetAFile
        .then(openFile) // Chain it!
        .then(function (fulfilled) { // If successful fileOpen.
            // Get a message after file opened!
            // Output: File file.mp3 opened!
            console.log(fulfilled);
        })
        .catch(function (error) {
             // Network Error!
             // Output: There is a problem with the network.
             console.log(error.message);
        });

console.log("End app.."); // ***

 
Voir aussi la fonction et la fonction fléchée dans ECMAScript :

6- ES7 - Async Await

ECMAScript-7 introduit les syntaxes  async et  await. Il permet d'utiliser  Promise plus facilement et plus compréhensiblement.
chaining-promise-es7-example.js
// [ECMAScript 7 Syntax]

var isNetworkOK = true;

// An Asynchronous function return a Promise
async function downloadFile(url)  {
    console.log("Start downloading file ..."); // ***

    // A Promise
    var willIGetAFile = new Promise (
       (resolve, reject) => {

           if (isNetworkOK) {
               setTimeout( function() {
                   console.log("Complete the download process!"); // ***
                   var file = {
                       fileName: 'file.mp3',
                       fileContent: '...',
                       fileSize: '3 MB'
                   };
                   resolve(file); // fulfilled
               }, 5 * 1000); // 5 Seconds
           } else {
               var error = new Error('There is a problem with the network.');
               reject(error); // reject
           }
        }
    );

    return willIGetAFile; // Return a Promise.
}

// An Asynchronous function return a Promise
async function openFile(file) {
    console.log("Start opening file ..."); // ***

    var willFileOpen = new Promise(
       (resolve, reject) => {
             var message = "File " + file.fileName + " opened!"
             resolve(message);
        }
    );

    return willFileOpen; // Return a Promise.
}

// Main Function (Asynchronous function)
async function mainFunction()  {
    try {
        console.log("Start app.."); // ***

        // Call downloadFile(..) function with 'await' keyword:
        // It returns a File (Not Promise)
        var file = await downloadFile("http://example.com/file.mp3");

        console.log(file);

        // Call openFile(..) function with 'await' keyword:
        // It returns a String (Not Promise)
        var message = await openFile(file);

        console.log(message);

        console.log("End app.."); // ***
    } catch(e)  {
       console.log(e.message);
    }
}

// Call Main Function:
(async () => {
    await mainFunction();
})();

 

View more Tutorials: