Async and await functions in NodeJs

Async and await functions in NodeJs

In this article, you will be learning about the use of async and await in NodeJS.

async await function in nodejs
Async – Await function in nodeJS

Async and await functions simplify a callback or promise in Node. These functions are readily available. It can be accessed through its declaration async and await. These functions will always return a promise.

Please check this link if you don’t know how to install nodejs on ubuntu.

To properly understand what Async functions are, it is necessary to understand the differences between Asynchronous functions and Synchronous functions.

Understanding Asynchronous and Synchronous functions

Synchronous functions also called “blocker” are functions go through the code line by line. It waits for a task to finish before picking up the next.

A real-life example of this is at a salon. Imagine a scenario where there is only one barber present at the salon. The barber is already attending to a customer. A new customer will have to wait before getting a haircut. The barber cannot halt the task to attend to the new customer. This process runs sequentially based on the time of arrival. This process is synchronous.

Let’s see a program example a synchronous function;

const syncCheck=()=>{
  console.log("FIRST")
}
syncCheck();
console.log("SECOND");
console.log("THIRD");

The result from syncCheck function shows that the tasks are executed one after the another.

These functions waste about 90% of CPU cycles waiting for a network or I/O operation.

Asynchronous functions run “non-blocking” code that brings out better performance of operations. These functions execute (runs) without waiting for any external I/O resources needed.

A real-life explanation for these functions is waiters. A waiter gets an order from customer A and relates the information to the kitchen. The waiter continues taking orders from other customers while the process of preparing customer A’s is ongoing. When the order becomes ready, the waiter picks it and presents it to customer A.

This is an example of asynchronous function through a setTimeout callback function;

const asyncCheck=()=>{
  setTimeout(()=>
  console.log("FIRST")  
  ,1000)
}
asyncCheck(); 
console.log("SECOND");  
console.log("THIRD");  

The result displays the “SECOND” and “THIRD” as it waits for “FIRST” to resolve.

Async function and Promise

NodeJs is an asynchronous platform. It uses a callback function. The execution occurs at the completion of a task by preventing any blocking and permitting other codes to fire (run) in the meantime.
It does not wait for the completion of an I/O operation or database query.

const asyncOperation= () => {   
       return new Promise(resolve => {
         setTimeout(() => 
           resolve('Async operation performed.')
         , 3000)   
   }) }

An async function always returns a promise. Additionally, the await keyword is used inside an async function. With await, it is possible to wait for a promise to resolve or be rejected.

The keyword async appears before functional components.

async function asyncOperation{
    //Do something
}

It is also used in a callback function by putting the async before the callback.

const asyncOperation=async()=>{
  //do something
}

Now that we understand where to input async , let us take a look at an example of an async function.

const asyncFunction = () => {
   return new Promise(resolve => {
     setTimeout(() => resolve('First'), 3000)
   })
 }
 const showSomething= async () => {
   console.log(asyncFunction());
   console.log('Second');
 }
 showSomething();
 console.log('Third');

The result displayed is as follows;

async function without await

The function returns a promise. However, when logged into the console, the promise had not been resolved. Instead, the code ran without waiting for the response. The async function displays a promise that is yet to resolve before its execution by another line of code.

How do we solve this problem? We make use of await. An await expression enables the async function to execute to a pause (or block) until Promise is resolved or rejected. The execution of the async function continues till it’s resolved. The value present in the await expression is that of a resolved or rejected Promise after executing.

You might want to ask, is it necessary to always use await? await is used only when another line of code requires the data present in a promise before execution.

The keyword await is added before every promise.

const asyncFunction = () => {
   return new Promise(resolve => {
     setTimeout(() => resolve('First'), 3000)
   })
 }
 const showSomething= async () => {
   console.log(await asyncFunction());
   console.log('Second');
 }
 showSomething();
 console.log('Third');

The result of this code displays; (“Third, First, Second”). It happens because the await keyword ensures the fulfillment of the promise before being logged onto the console.

async function with await

Async functions and Callbacks

Let’s try using async and await to fetch data from an external API endpoint.

const FetchData= async()=>{
  const res= await fetch ("https://www.themealdb.com/api/json/v1/1/filter.php?i=chicken_breast"); //Here we attempt to fetch a list of meals with chicken breast
  //res in this instance returns a promise
  const userData = await res.json() // we parse res into a json
    console.log (userData);          //log the data to console         
}

Now, let us compare a typical Node callback function and async function. I will be querying a single country data from a list of countries and get the country’s capital.

const FetchCountryCapital = () => {
  return 
    fetch('https://restcountries.eu/rest/v2/all') //get country list
    .then(res => res.json()) // parse JSON
    .then(countries =>   
       countries[0]  
    ) // pick first user  // get user data
    .then(country=> country.capital)
    .then(name=>console.log(name))
    .catch(error=> 
             console.log("An error was found", error) 
              //log if error is found
         )      
} 

FetchCountryCapital()  

Using async and await, this can be better written as follows;

const FetchCountryCapital= async()=>{
  try {
    const res= await fetch ("https://restcountries.eu/rest/v2/all");
    //res in this instance returns a promise
    const countryData = await res.json()
    const country =  countryData[2];
    const capital =  country.capital; 
      console.log (capital); 
  } catch (error) {
    console.log("An error was found");//log if error is found
    
  }
} 
 
FetchCountryCapital()

Conclusion

The async-await function makes it easy to perform debugging. The compiler reads through an async function the same way it does with synchronous code. Debugging asynchronous codes is a tedious task since debuggers will not step over the asynchronous code.

Async-Await functions are essential to modern JavaScript development. It is necessary to understand how they work and to use them. I hope this article has been able to help with that.

Kindly leave a message in the comment section below if you have any questions.

Share This Post