Today i will share the Node JS callback and promise system. Node JS asynchronous event based language which mean system not wait for task for completion and forward to next instruction. So as an example if we try to read a file from file system and then print read contents that may not work.
const fs = require ("fs"); let content = fs.reafile ("file.txt"): console.log (content):
In above code, interpretor jump to console log even before read file call completion due to asynchronous behavior.
This issue is resolved by Node JS by making all its core APIs async friendly through callbacks. Above example actually work like below.
const fs = require ("fs"); let content = fs.reafile ("file.txt", function (err, data){ if (err ){ console.log (err); } console.log (data): }):
Here readfile api provide a callback function which executed after file read operation. It have two arguments err and data. Data have the success response, in case of readfile api, file contents.
Node JS core APIs work like that. Provide a callback function with error and response as parameters. We can implement our callbacks similar to this for asynchronous tasks.
funtion asyncfunction (inp, callback ){ // do some asyns task const http = require ("http"); http.get (url, function (err, response){ callback (response); }); }
Above function can be used like
asyncfunction( data, function (httpResponse) { console.log( httpResponse); });
In this case we can get interesting pattern like below.
func1(data, function() { data.mod1 = 1; func2(data, function() { data.mod2 = 2; func3(data, function() { data.mod3 = 3; func4(data, function() { data.mod4 = 4; console.log( data); }) }); }); });
Above code show hierarchy of callbacks, Also famously called Callback Hell. This is problematic due to Poor readability & Poor manageability. Their are multiple solutions for ignore callback hells.
First to use modular code like I previously done in asyncfunction.
Second approach is to use Promises. Promise give us better control of asynchronous code.
Promise have two results states. Resolve & Reject. In Core Node JS we can use promise like that
function MyPromisedFunc() { return new Promise( resolve, reject ) { http.get(url, function(err, response) { if( err ) { reject(‘Error in http response’) } resolve(response); }); }); } return MyPromisedFunc() .then(function(response) { console.log(response); }).catch(function(err) { console.log(err); });
Above code is more readable and manageable then callback code. Any time of our async code when we get actual response, we only need to resolve promise, If we get error the we reject the promise.
This further handle by then & catch blocks.
This is more look clear in multiple async function which need to run synchronously.
return MyPromisedFunc1() .then(MyPromisedFunc2) .then(MyPromisedFunc3) .then(MyPromisedFunc4) .then(function(response) { console.log(response); }).catch(function(err) { console.log(err); });
Now we executed four asynchronous functionalities in sync manner with better manageability.
Promise core api functionality is still very much limited in terms of functionality compare to third party Promise libraries like bluebird, Q Promise and more.
Example in bluebird support execution in parallel with better control.
const bluebirdPromise = require(‘bluebird’); return bluebirdPromise.all([ MyPromisedFunc1(), MyPromisedFunc2(), MyPromisedFunc3(), MyPromisedFunc4() ], .then(function(responseArray) { console.log(responseArray[0]); console.log(responseArray[1]); console.log(responseArray[2]); console.log(responseArray[3]); }).catch(function(err) { console.log(err); });