In JS world, promise
s always been a controversial topic. Interestingly, There are lots of libraries out there implementing promise in there own tastes. jquery’s deferred, q, bluebird, deferred.js to name just a few. Opinions conflict over using async, generators, callbacks etc. But thank God; ECMA has now officially implemented promises in ES6. That’s a good news for JS community over having a single standard implementation of promises.
Promises are in a way clean implement async programming in JavaScript (ES6 new feature). Prior to promises, callbacks were used to implement async programming.
Let’s dive in to first understand what async programming is?
Understanding Callback
Callback are most of the time a function passed into another function as a parameter and is called subsequently, if conditions of calling is met. This mechanism is known as callback.
Here is how it looks
var isWrittenToDisk;
function writeDone (){
console.log("Writing to disk is done.");
};
function writeFailed (){
console.log("Writing to disk has failed.");
};
function notifyWriteStatus (done, fail){
if(isWrittenToDisk){
done();
} else {
fail();
}
};
// typically this should be set in function writing to
// file, but for sake of simplicity we are assigining it
// to true
isWrittenToDisk = true;
notifyWriteStatus(writeDone, writeFailed);
console.log("Process is done!")
It would have output, similar to following
Writing to disk is done.
Process is done!
In notifyWriteStatus
method above calles appropriate method as per flag set in isWrittenToDisk
. If isWrittenToDisk
set to true, done
callback is called, else fail
callback
The above code snippet is synchronous and hence blocks the execution until a file written to disk. To overcome this we used to use non-blocking/asynchronous callbacks
In ES5 or before one can achieve async calls by wrapping them within setTimeout
method, that’s async by default.
Let’s conver above example to async call
var isWrittenToDisk;
function writeDone (){
console.log("Writing to disk is done.");
};
function writeFailed (){
console.log("Writing to disk has failed.");
};
function notifyWriteStatus (done, fail){
setTimeout(function(){
if(isWrittenToDisk){
done();
} else {
fail();
}
}, 3000);
};
// typically this should be set in function writing to
// file, but for sake of simplicity we are assigining it
// to true
isWrittenToDisk = true;
notifyWriteStatus(writeDone, writeFailed);
console.log("Process is done!")
It would have output, similar to following
Process is done!
Writing to disk is done.
The setTimeout
will wait for 3 seconds before executing notifyWriteStatus
method body. meanwhile our main program would be done executing
But, it becomes tedious to maintain when there are multiple nested callbacks, looks scary. And that’s where “callback hell” kicks in
ES6 Promises
ES6 comes to one’s rescue by introducing the concept of promises. Promises in nutshell are, continuing event; helping us to execute multiple async ops together as chained. Promises returns promise instance that can be chained and passed on to chained function.
Let’s dive in
new Promise ((resolve, reject) => {
if (Math.random() * 10 <= 9) {
resolve('Yay!');
}
reject(new Error('I failed!'));
}).then (
(resolveValue) => { console.log(resolveValue) },
(error) => { console.log(error) }
)
In example above, promise object returns a promise and passes onto next then function that, in turn passes function to be called on resolve or reject state and passes it to caller.
Promises can be chained multiple times, the only condition is that return value should be an object of promise. Let’s see
function randomRoll(){
return new Promise ((resolve, reject) => {
if (Math.random() * 10 <= 9) {
resolve('Yay!');
} else {
reject(new Error('I failed!'));
}
})
};
randomRoll()
.then(
(resolveValue) => {
console.log("Done. Redoing...");
randomRoll();
},
(rejectValue) => {
console.log("Failed. Miserably :(");
randomRoll();
}
).then(
(resolveValue) => {
console.log("Done. Resting...");
},
(rejectValue) => {
console.log("Failed. Miserably :( Again!!");
}
)
ES6 comes to your rescue by introducing the concept of promises. Promises are “Continuation events” and they help you execute the multiple async operations together in a much cleaner code style.
About The Author
I am Pankaj Baagwan, a System Design Architect. A Computer Scientist by heart, process enthusiast, and open source author/contributor/writer. Advocates Karma. Love working with cutting edge, fascinating, open source technologies.
To consult Pankaj Bagwan on System Design, Cyber Security and Application Development, SEO and SMO, please reach out at me[at]bagwanpankaj[dot]com
For promotion/advertisement of your services and products on this blog, please reach out at me[at]bagwanpankaj[dot]com
Stay tuned <3. Signing off for RAAM