We all know that JavaScript is the synchronous and single-threaded programming language. That is to say, only one task can perform at any point in time. But on the contrary, JavaScript also provides the ability to make it behave like an asynchronous language with the help of promises mechanisms.  Async and Await concept, which introduced in ES 2017, is an advanced way of handling "Promises in JavaScript". In this article, we will cover the following topics to understand the details of the JavaScript Async Await clause:

  • Why do we need an Async function in JavaScript?
  • How to use the JavaScript Async-Await clause to handle Promises in JavaScript?
  • How to handle the Pyramid of Doom with the async-await in JavaScript?

Why do we need an Async Function in JavaScript ?

Async functions enable the programmer to write promise-based code, which appears like a synchronous code but doesn't block the main thread of execution. Asynchronous functions operate in a different order than the rest of the code via the event loop, returning an implicit Promise as its result, but the syntax and structure of code using async functions look like standard synchronous functions only. Its syntax looks like below:

Syntax:

async function functionName(){

  // action to be performed;


}

As we have seen in the previous articles, we can achieve async behavior in JavaScript using the Promises. The below code snippet makes it more clear:

<html>
   <meta charset="utf-8"/>
<body> Understanding JavaScript Program Execution</br>
    <script type="text/javascript">
    	function i_take_10_sec()
    	{
    	 	 return new Promise((resolve,reject)=>{	setTimeout(() => { 
               console.log('I was no: 2 and I take 10 second');
               resolve();
    	 		}, 10000);
            });
    	}
 
    	async function run()
    	{
         console.log('I was no: 1 and I executed immediately');
    	 i_take_10_sec();
         console.log('I was no: 3 and I should have executed after 2');
    	}
      
    	run();
       
    </script>
</body>
 
</html>

Save the file with name javaScriptExecution.html and open it in any browser (Chrome, Firefox, or IE). It should show the output as:

Async function execution in JavaScript

As we see, the output JavaScript will trigger the run function, but it does not wait until the execution of that function i_take_10_sec() completes. We can confirm the same from the order of the print statements on the browser's console on the right side of the above image.

Note: Even if we don't use the async keyword in the function definition, JavaScript will make the function as asynchronous, which invokes a function that returns a promise. Therefore, even if we wrote the above program without the "async" keyword, the result would be the same.

But there can be some cases where the scripts need to wait until the previous step execution gets complete. In JavaScript, that one can achieve by promise handling, and an easy way of handling promises is the async-await clause.

How to use the JavaScript Async-Await clause to handle Promises in JavaScript?

The await keyword waits for the script until the function settles its promise and returns the result. We can use the await keyword only inside the async functions. It will pause the "async" function and wait for the Promise to resolve before moving on. Its syntax looks like below:

Syntax:

// works only inside async functions
let value = await promise;

Let's take the above example and convert it to execute in proper order with the help of promises and async-await.

<html>
   <meta charset="utf-8"/>
<body> Understanding JavaScript Program Execution</br>
    <script type="text/javascript">
    	function i_take_10_sec()
    	{
    	 	 return new Promise((resolve,reject)=>{	setTimeout(() => { 
               console.log('I was no: 2 and I take 10 second');
               resolve();
    	 		}, 10000);
            });
    	}
 
    	async function run()
    	{
         console.log('I was no: 1 and I executed immediately');
    	 await i_take_10_sec();
         console.log('I was no: 3 and I should have executed after 2');
    	}
      
    	run();
       
    </script>
</body>
 
</html>

Save the file with name asyncAwait.html and open it in any browser (Chrome, Firefox, or IE). It should show the output as: Async Await clause in JavaScript

As we see the output of the above code, the script will wait under i_take_10_sec() to get completed, i.e., until it is get resolved or rejected.

The "await" clause can only be used only inside async methods. That is to say, in normal methods, we cannot use "await" unless we don't use async keyword in the method signature

How to handle the Pyramid of Doom with the Async-Await clause?

We have seen a pyramid of doom problem in our JavaScript Callbacks and how to solve it in simple with the help of Javascript Promises. But with the help of promises still, it makes a user complicate to understand the code and maintain it. Because, the function call chain was again using "then()" method which can chain to the nth level and can again make the mode unreadable and non-maintainable. But with the help of async-await, there is no need for chaining for ensuring order between function calls, So the code is much cleaner and understandable.

Let's try to solve the same problem from callbacks and promises with the help of async-await.

<html>
    <meta charset="utf-8"/>
	<body> Handling pyramid of doom with help of async-await in javascript:</br>
	    <script type="text/javascript">
	 		function i_take_10_sec()
	    	{
	    	 	return new Promise((resolve, reject)=>{
	    	 	 	setTimeout(() => {
	    	 	 		console.log('I was no: 1 and I take 10 seconds'); 
	    	 			resolve();
	    	 		}, 10000);
				})
	    	 }
	 		function i_take_1_sec()
	    	{ 
	    		return new Promise((resolve, reject)=>{
	    			setTimeout(() => {
	    				console.log('I was no: 2 and I take 1 second'); 
	    				resolve();
	    			}, 1000);
	    		}) 
	    	}
	 		function i_take_5_sec(callback) 
	    	{ 
	    		return new Promise((resolve, reject)=>{
	    		 	setTimeout(() => {
	    		 		console.log('I was no: 3 and I take 5 second'); 
	    				resolve();
	    			}, 5000); 
	    		})
	    	}
			function i_take_7_sec(callback) 
	    	{ 
	    		return new Promise((resolve, reject)=>{
	    			setTimeout(() => {
	    				console.log('I was no: 4 and I take 7 second') ;
	    				resolve();
	    			}, 7000);
	    		}) 
	    	}
			async function run()
	    	{
	    	  await i_take_10_sec();
	          await i_take_1_sec();
	          await i_take_5_sec();
	          await i_take_7_sec();
	 		}
	 		run();
	 	</script>
	</body>
 </html>

Save the file with name async-await.html and open it in any browser (Chrome, Firefox, or IE). It should show the output as Handling Pyramid of Doom with Async Await clause

As we can see in the above code and screenshot, it is much simpler to read and maintain the promise-based code, as compared to nested callbacks or invoking promises using the .then() method.

Key Takeaways

  • One can declare the Async functions in JavaScript by specifying the "async" keyword in front of the function definition.
  • For handling the async functions, you can use the "await" keyword while invoking to function to wait for the promise to resolve.
  • Usage of async and await makes the program very clean and understandable. The reason being, there is no need to explicitly specify the dependencies of function calls using the ".then()" method.

Let's now move to the next article to understand a significant operator in JavaScript, knows as "Arrow Operator".

Closures in JavaScript
Closures in JavaScript
Previous Article
Arrow Function in JavaScript
Arrow Function in JavaScript
Next Article
Arunkumar Chandra
Test USer
Reviewers
Ravinder Singh's Photo
Ravinder Singh

Similar Articles

Feedback