2/9/19

Refactor Promises Functions into Async Await Functions

 With the release of Nodejs 8.10, we are now able to write asynchronous functions by using the async/await declarations.  This simplifies the use of promise chain in our code with a much simpler syntactic style.  To understand this better, let’s take a look at how asynchronous functions where written using Promises and how to refactor them using async/await declarations instead.





Simple Use Case

The code snippet below simulates a remote API call to get a product price and tax information. For simplicity, we are using a timer which enables us to create an asynchronous call. Basically, this enables us to not block the execution and return the result within less than a millisecond in a promise.
In our example, we want to show a common use case in which API calls may need to be made in a particular order. In our case, we want to be able to add the results from our two calls to get the final price. 


function getPrice(item){
  var products = {"shirt":15.99,"shoes":35.99};
  console.log("getprice",item);
 
  let promise = new Promise((resolve, reject)=>{

    /**we queue this call to return a promise once the timeout event is raised */
    setTimeout(()=>{
      let price =products[item];   
      resolve(price);
    },250);
   
  });

  return promise;
}

function getTax(value){

  console.log("gettax",value);
 
  let promise = new Promise((resolve, reject)=>{
    /**we queue this call to return a promise once the timeout event is raised */
    setTimeout(()=>{
      let price =value * 0.06;
      resolve(price);
    },250);
   
  });

  return promise;
}



Using Promises:

We want to call our APIs first using promises. This lets us illustrate a common pattern in which promises are chained together to process the results.


function getPricePromise(){

  var result = 0;

  let task1 =  getPrice("shirt");

  task1.then((value)=>{
    result += value;
    let task2 = getTax(value); 

    task2.then((value)=>{
      result += value;
      console.log('Promise',result); 
    });

  });



As shown in the code, the second API call to get the tax amount depends on the result of the first call. Therefore, we first get the price and process the returning promise with the then() method. This enables us to get the price value and chain the promise with another API call in which we get the tax amount and add the results. We must chain the calls because when using asynchronous calls the execution continues, and it does not wait for the return. We must process the promise to read the result.

async/await

The async and await declarations have been available in other languages like .NET for some time.  This feature was sorely missed in the JavaScript world. It basically helps us write asynchronous programming without having the complexity of chaining promises. Let’s refactor our previous code from promises to async/await calls.


async function getPricekAsync(){
   let result = 0;
       
   result = await getPrice("shirt");
   result += await getTax(result); 

   console.log("Async",result); 
}



As we can see from the code, we call the getPrice API, but the execution waits from the promise to be resolved by using the await declaration. Once the promise is resolved, the value is returned. This enables us to then call the second API and get the tax value. As we can see, we are no longer dealing with promises explicitly and the complexity of chaining then. Our code just follows normal coding practices and it is clear to follow thus increasing the maintainability index of the code.

How this works:

With the async/await declarations, we declare a function as asynchronous by using the async declaration as a prefix to the function name. In the function, we need to use the await declaration for any long running asynchronous tasks.  We should note that this is a requirement. We must use one or more await declarations within an async function.  

We need to remember that JavaScript is single threaded.  The asynchronous declaration does not mean that a background threats is created. It only means that promises are still being used in the background to manage the asynchronous operations.  It however allows the main thread to handle other events and execute until the promise is returned which leads to better performing and responsive apps.

I hope this provides some ideas on how to start replacing your full of promises code into a more descriptive asynchronous syntax.

Originally published by ozkary.com

0 comments :

Post a Comment