Understanding async and await in JavaScript
Tags: javascript, async, await, promise
Published: 2020-05-10 08:49:46

Before reading this article one should have good understanding of callbacks,Promises of JavaScript.
  If you not ware of them still,i recommend you to go through my articles
  [callbacks](https://dev.to/rajesh04159786/callbacks-in-javascript-5210) 
  [Promises](https://dev.to/rajesh04159786/understanding-javascript-promises-pkh)


Let us see the definition of async and await from documentation

"An async function is a function declared with the async keyword. Async functions are instances of the AsyncFunction constructor, and the await keyword is permitted within them. The async and await keywords enable asynchronous, promise-based behavior to be written in a cleaner style, avoiding the need to explicitly configure promise chains"

That means async and await are developed based on promises. One can write code to work asynchronously using async and await very easily and code is in very clean format.

async
-----
Let us understand async first.
Consider the following function.
{% runkit

%}
async function test(){

}
console.log(test())
 
{% endrunkit %}


It returns a Promise object whose status is "resolved" and value is "undefined".
That means an async function returns promise.

Let us return some value by this function
{% runkit

%}
async function test(){
       return 100;
}
test().then((value)=>value)
 
{% endrunkit %}
 Now the value of promise object is 100.


It is same as explicitly returning promise like below

{% runkit

%}
async function test(){
       return Promise.resolve(100);
}
test().then((value)=>value)
 
{% endrunkit %}


Now, we are very clear about await function.Let us focus on async.

await
-----
"Async functions can contain zero or more await expressions. Await expressions suspend progress through an async function, yielding control and subsequently resuming progress only when an awaited promise-based asynchronous operation is either fulfilled or rejected"
That means "an await expression" suspends progress until the async function of that expression completes its execution.
syntax:
**let value=await promise;**


Let us understand this with an example
{% runkit

%}
function waitForTaskStatus(){
   return new Promise((resolve,reject)=>{
    setTimeout(() => {
        resolve("task completed")
    }, 2000);
   })
}

async function test(){
    console.log("waiting for task status")
    let status=await waitForTaskStatus();
    return status;
}
test();
 
{% endrunkit %}


We just experienced asynchronous nature of  await expression which suspends the progress until the "waitForTaskStats()" function is executed.Then only the rest of statements of "test() function" will get chance to execute.

By using "await" ,we can avoid calling "then()" on promise object to deal with its resolve status.

*The await keyword is only valid inside async functions. If you use it outside of an async function's body, you will get a SyntaxError.*

*The purpose of async/await is to simplify the syntax necessary to consume promise-based APIs. The behavior of async/await is similar to combining generators and promises.*


Now let us implement the use what i considered in my 
[article on callbackscallbacks](https://dev.to/rajesh04159786/callbacks-in-javascript-5210) ,
  [article on Promises](https://dev.to/rajesh04159786/understanding-javascript-promises-pkh)
which is " *find big number of given two numbers,add 100 to to it and subtract 10 from the result* ". Let us implement the same using async and await.


{% runkit

%}
function finBig(first,second){
    return new Promise((res)=>{
       
            setTimeout(() => {
                if(first>second|| first==second){
                    console.log("big number is ",first);
                    res(first);
                }
                else{
                    console.log("big number is ",second);
                    res(second);
                }
            }, 2000);
     
   
    });
}

function incrementResultBy100(bigNumber){
    return new Promise((res)=>{
        
            let bigNUmberAddedBy100=bigNumber+100;
            console.log("big number after added with 100 is  is ",bigNUmberAddedBy100);
            res(bigNUmberAddedBy100);
       
        }
    )}


function decreaseResultBy10(bigNUmberAddedBy100)
{
    return new Promise((res)=>{
       
            setTimeout(() => {
                let result=bigNUmberAddedBy100-10;
              //  console.log("result after decrement of 10 is  is ",result);
                 res(result);
            }, 1000);
           
       
    });
}



function test(){
return finBig(100,200).then((bigNumber)=>{
    
    return incrementResultBy100(bigNumber)
}).then((bigNUmberAddedBy100)=>{
   
    return decreaseResultBy10(bigNUmberAddedBy100);
}).then(result=>{
    
    console.log("final result  after decreasing 10 is ",result)
}).catch((err)=>{console.log("err is ",err)});

}

test();
 
{% endrunkit %}




Now, let us rewrite the above using async and await which can be more clean like below

{% runkit

%}
function finBig(first,second){
    return new Promise((res)=>{
      
            setTimeout(() => {
                if(first>second|| first==second){
                    console.log("big numbe is ",first);
                    res(first);
                }
                else{
                    console.log("big numbe is ",second);
                    res(second);
                }
            }, 2000);
     
    
    });
}

function incrementResultBy100(bigNumber){
    return new Promise((res)=>{
      
            let bigNUmberAddedBy100=bigNumber+100;
            console.log("big number after added with 100 is  is ",bigNUmberAddedBy100);
            res(bigNUmberAddedBy100);
     
        }
    )}


function decreaseResultBy10(bigNUmberAddedBy100)
{
    return new Promise((res)=>{
      
            setTimeout(() => {
                let result=bigNUmberAddedBy100-10;
              //  
                 res(result);
            }, 1000);
           
      
    });
}






async function test(){
    try{
    const bigNumber=await finBig(1000,200);
    const bigNUmberAddedBy100=await incrementResultBy100(bigNumber);
    const result=await decreaseResultBy10(bigNUmberAddedBy100);
    console.log("result after decrement of 10 is  is ",result);
    }
    catch(err){
        console.log("err is ",err)
    }
}

test()

    








 
{% endrunkit %}





Summary
------
The async keyword before a function has two effects:

Makes it always return a promise.
Allows await to be used in it.
The await keyword before a promise makes JavaScript wait until that promise settles, and then:

If it’s an error, the exception is generated — same as if throw error were called at that very place.
Otherwise, it returns the result.