o7planning

ECMAScript Promise, Async/Await Tutorial with Examples

View more Tutorials:

Follow us on our fanpages to receive notifications every time there are new articles. Facebook Twitter

1- What is Promise ?

In computer programming, you often work with functions, and when calling a function, you almost get the returned result immediately. 


function sum(a, b)  {
  return a + b;
}

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

console.log(result);
 
Suppose that you create a function called downloadFile(url) to download a file from the Internet
Downloading a large file may take several minutes or longer. When calling the downloadFile(url) function synchronously, it will freeze all user's actions until it completes. Thus, during the time when the file is being downloaded, the user can not manipulate with the application. 
Therefore, you can't expect a function as follows:

// Call download:

var myfile = downloadFile("http://example.com/file.mp3");
Promise?
  • The answer is that this function should return a Promise instead of a file.
Let's imagine that your beautiful girlfriend tells you "Please marry me!". Okey, of course, but you can't do it immediately because you need more time to prepare, but she's waiting for your answer, and it's best to give her a promise, and immediately both are happy.  
Promise State?
A Promise has 3 states:
State Description
Pending The Promise is in progress, you cannot know whether it will succeed or fail. For example, the file is being downloaded.
Fulfilled The mission of the Promise has been completed. For example, the file has been successfully downloaded.
Rejected The mission of the Promise failed. For example, there was an error during the download process.
Syntax for creating an  Promise object:


new Promise (
      function (resolve, reject) {
           // Codes
      }
);
Example:

// [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
        }

    }
);
Your downloadFile(url) function will return a Promise object as follows:

// [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- Use Promise

In the above part, we have the downloadFile(url) function, which returns a Promise object. Now we will learn about how to use this function. 

// 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);
        });
Okay,This is full code of this example:
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);
        });
 
If isNetworkOK = true, when running the example, you receive the result:
If isNetworkOK = false, when running the example, you get the result:

3- Chaining Promise

Chaining Promise is a set of consecutive Promises that are brought together.
Please imagine that you need to do the 2 actions including: calling the downloadFile(url) function to download a file from the Internet, and then call the openFile(file) function to open the file just downloaded.
Downloading a file from the Internet takes some time. The downloadFile(url) function is designed to return you a Promise. You can only have files to open if  downloading is successful. Therefore, you should also design the openFile(file) function to return a Promise
Write the openFile(file) function to 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.
}
Instead of creating a Promise object via the new operator, you can use static Promise.resolve(value) or Promise.reject(error) methods.  These two methods return a Promise object.    
You can write an openFile(file) function again more shortly:

// 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;
}

 
Call the downloadFile(url) function and openFile(file) function in the Promise style:

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.."); // ***
See the full code of the example:
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);
        });
 
Run the example and receive the result:

4- Promise is asynchronous

Promise is Asynchronous. That means when you call a Promise function (Function returns 1 Promise). It will not freeze your application during the time while the Promise is being performed.
To clarify this issue, we correct the above example a little bit. Use the setTimeout() function to simulate the taking some time by downloading a file.
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.."); // ***
 
 
The result that you receive when running the above example:
Please pay attention to the order in which the messages are printed out on the Console screen:

Start app..
Start downloading file ...
End app..
Complete the download process!
Start opening file ...
File file.mp3 opened!

5- Promise in ES6

ECMAScript-6 is included a Narrow Function syntax, therefore, you can rewrite the above example by the ES6 syntax:
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.."); // ***

 
See also the function and arrow in ECMAScript:

6- ES7 - Async Await

ECMAScript-7 introduces the async and await syntax. We help using Promise easier and more understandable
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:

Maybe you are interested

These are online courses outside the o7planning website that we introduced, which may include free or discounted courses.