Async/Await, Modern way of writing nodejs code

The biggest problem with understanding the nodejs  code is to follow the callbacks. Probably reading out someone else’s code is the hardest job for any developer. Nodejs adopted to write down callbacks for each and every task to achieve maximum parallelism. But this is the most pinching part of any newbie to understand.

 

Most of the beginners do not realize the sequence of below code:

 

[gist  filename=”code1.js” url=”isummation/9d16b3082c36f7becce3480c685d990c” public=”true”]

setTimeout(function(){

console.log(“callled later”);

}, 1000);

 

console.log(“Called first”);

[/gist]

In reality, most of the time you will need parallelism when iterating over an array. Probably the best way is to use the eachLimit method of the async module link. Again, looping will also have subtask with their own callbacks, and that will again increase the complexity. For example, you have a bunch of physical paths and you want to read each file and replace some characters and then write them again.  This is the classic case that we can read files parallelly but we can write the files only after the read process is completed.

 

People also use the promise libraries like q and bluebird, to chain some tasks but again, most of the item you can not chain all your tasks. Eventually, you’ll realize that writing sequential code was much easier and simple to traverse.

 

Async/Await Nodejs

 

async/await is a new way of writing code. You can use it with the help of promises.  For example, I have used bluebird for promisifying the google map module. Notice that I’ve also promisify the setTimeout function for delayed processing.

 

[gist  filename=”GoogleMapService.js” url=”isummation/66b81d16cd6c0d12602d4e3864e221b1″ public=”true”]

const _config = require(‘../config’);

 

const sql = require(‘mssql’);

 

var GoogleMapService = {};

 

GoogleMapService.init = async function() {

try {

GoogleMapService.googleMapsClient = require(‘@google/maps’).createClient({

key: _config.GoogleMapKey,

Promise: require(“bluebird”).Promise

});

 

GoogleMapService.pool = await new sql.ConnectionPool( _config.mssql ).connect();

let tableData = await GoogleMapService.pool.request()

.query(

select id, lat, lng

from tblAddress

where altitude is null

 

)

for (let obj of tableData.recordset){

let res = await GoogleMapService.googleMapsClient.elevation({

locations: {

lat: obj.lat,

lng: obj.lng

}

}).asPromise();

if (res.json.status == “OK”) {

await GoogleMapService.pool.request()

.input(‘altitude’, sql.Float, res.json.results[0].elevation )

.input(‘id’, sql.Int, obj.propertyId)

.query(

UPDATE tblAddress

SET altitude = @altitude

WHERE id = @id

 

)

console.log( “tblAddress Updated”, { result: res.json, property : obj } );

} else if (res.json.status == “OVER_QUERY_LIMIT”) {

console.error( “Limit execeed”, { result: res.json, property : obj } );

break;

} else {

console.error(“Logging other errors”, { result: res.json, property : obj } );

}

await GoogleMapService.sleep(2000); //sleep 2 second

}

GoogleMapService.terminate();

} catch (e) {

console.log(“Google Map Service Error”, e);

GoogleMapService.terminate();

}

}

 

GoogleMapService.terminate = function(){

GoogleMapService.pool.close();

}

 

GoogleMapService.sleep = function(ms){

return new Promise(resolve=>{

setTimeout(resolve,ms)

})

}

 

GoogleMapService.init();

[/gist]

Node developers can have much better async/await flow for Node 8 or Newer version as it is fully supported.

 

Node.js library async/await offer own cross-platform versions of the feature.

 

Async/Await is now available in all new versions of most major browsers, except IE11. All other browsers recognize async/await code without the need of external libraries.