JavaScript Async / Await

Leave a comment

In some previous posts, we looked at using callbacks and promises. In this post, we will look at Await / Async in JavaScript.

Await / Async is built on promises, and is a clean way to represent asynchronous processes in a synchronous way.

For example, consider the code below. We have 2 functions, DoSomethingAsync and DoSomethingElseAsync.  The first function will complete in 2 seconds, and the second function in 1 second:

    function DoSomethingAsync() {
        return new Promise(function(resolve, reject) {
            // This will be resolved successfully in 2 seconds
            setTimeout(function() {
                console.log("Finished DoSomethingAsync");
                resolve();
            }, 2000);            
        }
    )}

    function DoSomethingElseAsync() {
        return new Promise(function(resolve, reject) {
            setTimeout(function() {
                console.log("Finished DoSomethingElseAsync");
                resolve();
            }, 1000);
        }
    )}
    
    function Run() {

          DoSomethingAsync();
          DoSomethingElseAsync();

          console.log("Finished!");
    }

    Run();

If we were to run this code, we would get the following output. The “Finished!” line will be printed first as each of these lines of code is run sequentially, then the DoSomethingElseAsync, which takes less time to run than the DoSomethingAsync function, which is actually called before it:

We can change this code to use async and await. Rewriting our functions, we can use the async keyword and return a promise. We will then run each function using the await keyword:


    async function DoSomethingAsync() {
        return new Promise(function(resolve, reject) {
            // This will be resolved successfully in 2 seconds
            setTimeout(function() {
                console.log("Finished DoSomethingAsync");
                resolve();
            }, 2000);            
        }
    )}

    async function DoSomethingElseAsync() {
        return new Promise(function(resolve, reject) {
            setTimeout(function() {
                console.log("Finished DoSomethingElseAsync");
                resolve();
            }, 1000);
        }
    )}
    
    async function RunAsync() {

          let result = await DoSomethingAsync(); // wait until the promise resolves
          let result2 = await DoSomethingElseAsync(); // wait until the promise resolves

          console.log("Finished!"); // "done!"
    }

    RunAsync();

In doing this, our code actually runs as if each statement were waiting for the previous one to complete:

This makes the code very readable, compared to using just promises, or just callbacks.

You can also use try/catch to handle errors:

async function DoSomethingAsync() {
    return new Promise(function(resolve, reject) {
        // This will be resolved successfully in 2 seconds
        setTimeout(function() {
            console.log("Finished DoSomethingAsync");
            reject("An error has occurred");
        }, 2000);
    }
)}

async function RunAsync() {
    try {
        let result = await DoSomethingAsync(); // wait until the promise resolves
    }
    catch(error) {
        console.error(error);
    }

    console.log("Finished!"); // "done!"
}

RunAsync();
ABOUT CARL DE SOUZA

Carl de Souza is a developer and architect focusing on Microsoft Dynamics 365, BI, Web, Cloud and Data Science.

carldesouza.comLinkedIn Twitter | YouTube

 

Leave a Reply

Your email address will not be published. Required fields are marked *