- September 28, 2017
- Posted by: Vikas
- Category: Uncategorized
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 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.