Understanding promises in Node.js
Since this question still has many views (like mine) I wanted to point out that:
- node-promise looks rather dead to me (last commit was about 1 year ago) and contains nearly no tests.
- The futures module looks very bloated to me and is badly documented (and I think that the naming conventions are just bad)
- The best way to go seems to be the q framework, which is both active and well-documented.
Promises in node.js promised to do some work and then had separate callbacks that would be executed for success and failure as well as handling timeouts. Another way to think of promises in node.js was that they were emitters that could emit only two events: success and error.
The cool thing about promises is you can combine them into dependency chains (do Promise C only when Promise A and Promise B complete).
By removing them from the core node.js, it created possibility of building up modules with different implementations of promises that can sit on top of the core. Some of these are node-promise and futures.
A promise is a "thing" which represents the "eventual" results of an operation so to speak. The point to note here is that, it abstracts away the details of when something happens and allows you to focus on what should happen after that something happens. This will result in clean, maintainable code where instead of having a callback inside a callback inside a callback, your code will look somewhat like:
var request = new Promise(function(resolve, reject) {
//do an ajax call here. or a database request or whatever.
//depending on its results, either call resolve(value) or reject(error)
//where value is the thing which the operation's successful execution returns and
//error is the thing which the operation's failure returns.
});
request.then(function successHandler(result) {
//do something with the result
}, function failureHandler(error) {
//handle
});
The promises' spec states that a promise's
then
method should return a new promise that is fulfilled when the given successHandler or the failureHandler callback is finished. This means that you can chain together promises when you have a set of asynchronous tasks that need to be performed and be assured that the sequencing of operations is guaranteed just as if you had used callbacks. So instead of passing a callback inside a callback inside a callback, the code with chained promises looks like:
var doStuff = firstAsyncFunction(url) {
return new Promise(function(resolve, reject) {
$.ajax({
url: url,
success: function(data) {
resolve(data);
},
error: function(err) {
reject(err);
}
});
};
doStuff
.then(secondAsyncFunction) //returns a promise
.then(thirdAsyncFunction); //returns a promise
To know more about promises and why they are super cool, checkout Domenic's blog : http://domenic.me/2012/10/14/youre-missing-the-point-of-promises/
This new tutorial on Promises from the author of PouchDB is probably the best I've seen anywhere. It wisely covers the classic rookie mistakes showing you correct usage patterns and even a few anti-patterns that are still commonly used - even in other tutorials!!
- http://pouchdb.com/2015/05/18/we-have-a-problem-with-promises.html
Enjoy!
PS I didn't answer some other parts of this question as they've been well covered by others.