Understanding promises in Node.js
Asked Answered
D

9

152

From what I have understood there are three ways of calling asynchronous code:

  1. Events, e.g. request.on("event", callback);
  2. Callbacks, e.g. fs.open(path, flags, mode, callback);
  3. Promises

I found the node-promise library but I don’t get it.

Could someone explain what promises are all about and why I should use it?

Also, why was it removed from Node.js?

Divebomb answered 28/11, 2010 at 11:27 Comment(2)
This article explains it rather well. When it comes to an implementation usable in node.js, take a look at FuturesNeat
Here's a great series I've used to create my own promise class: Let's Make a Framework: Promises Here's video about jQuery Deferred: blog.bigbinary.com/2011/09/03/jquery-deferred.htmlNoach
S
92

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.

Sackville answered 28/11, 2010 at 14:5 Comment(0)
E
98

Since this question still has many views (like mine) I wanted to point out that:

  1. node-promise looks rather dead to me (last commit was about 1 year ago) and contains nearly no tests.
  2. The futures module looks very bloated to me and is badly documented (and I think that the naming conventions are just bad)
  3. The best way to go seems to be the q framework, which is both active and well-documented.
Eureetloir answered 16/5, 2012 at 20:41 Comment(3)
Check also this github.com/medikoo/deferred , Q is one of the first and it's definitely inspiration to many implementations that appeared afterwards, but unfortunately it's very slow and too "theoretical" in some parts, it doesn't play well with some real world scenariosAllerie
I'd check out this video on promises by one of the creators of RSVP.js youtube.com/…Spy
2014 update - bluebird is by far the fastest and the one with the best debugging abilities today.Sequel
S
92

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.

Sackville answered 28/11, 2010 at 14:5 Comment(0)
O
20

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/

Ornelas answered 23/5, 2014 at 16:11 Comment(0)
T
12

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!!

Enjoy!

PS I didn't answer some other parts of this question as they've been well covered by others.

Timmons answered 25/5, 2015 at 1:39 Comment(4)
My only apology for this is forcing you to read humor at the end of Advanced mistake #4.Polluted
In fact, the code in the tutorial that they claim to be an antipattern needs the nesting for the loop and the condition, and cannot be as easily flattened as they suggest.Verified
Advanced mistake #4 can also be solved using a far greater number of different approaches, see How do I access previous promise results in a .then() chain? (the closure pattern they suggest doesn't seem to be very popular).Verified
I think this link-only answer should've better been a comment. Please put at least the main points of that article in your answer here.Verified
H
7

Mike Taulty has a series of videos, each of them less than ten minutes long, describing how the WinJS Promise library works.

These videos are quite informative, and Mike manages to show the power of the Promise API with a few well-chosen code examples.

var twitterUrl = "http://search.twitter.com/search.json?q=windows";
var promise = WinJS.xhr({ url: twitterUrl });

 promise = promise.then(
     function (xhr) {
     },
     function (xhr) {
         // handle error
     });

The treatment of how exceptions are dealt with is particularly good.

In spite of the WinJs references, this is a general interest video series, because the Promise API is broadly similar across its many implementations.

RSVP is a lightweight Promise implementation that passes the Promise/A+ test suite. I quite like the API, because it is similar in style to the WinJS interface.

Update Apr-2014

Incidentally, the WinJS library is now open source.

Hebraism answered 13/12, 2012 at 15:0 Comment(3)
+1. This is the first example I've seen that makes sense to me and is intuitive to use. Somehow my brain cannot parse all the deferreds and resolve and deferred.promise.then and predefining of promiseActions in the popular Q library documentation. Any chance you know something this straightforward for Node.js?Hypercritical
@noel thank you for sharing the above link, it is an excellent introductory series for promises, and I agree the WinJS specifics are irrelevant as the overall approach / topic is universal.Gratia
Nice example. Also I fixed up your first link which was deadCelina
G
5

Another advantage of promises is that error handling and exception throwing and catching is much better than trying to handle that with callbacks.

The bluebird library implements promises and gives you great long stack traces, is very fast, and warns about uncaught errors. It also is faster and uses less memory than the other promise libraries, according to http://bluebirdjs.com/docs/benchmarks.html

Gonidium answered 14/3, 2014 at 15:30 Comment(0)
N
4

What exactly is a Promise ?

A promise is simply an object which represents the result of an async operation. A promise can be in any of the following 3 states :

pending :: This is the initial state, means the promise is neither fulfilled nor rejected.

fulfilled :: This means the promise has been fulfilled, means the value represented by promise is ready to be used.

rejected :: This means the operations failed and hence can't fulfill the promise. Apart from the states, there are three important entities associated to promises which we really need to understand

  1. executor function :: executor function defines the async operation which needs to be performed and whose result is represented by the promise. It starts execution as soon as the promise object is initialized.

  2. resolve :: resolve is a parameters passed to the executor function , and in case the executor runs successfully then this resolve is called passing the result.

  3. reject :: reject is another parameter passed to the executor function , and it is used when the executor function fails. The failure reason can be passed to the reject.

So whenever we create a promise object, we've to provide Executor, Resolve and Reject.

Reference :: Promises

Nolde answered 18/5, 2017 at 20:18 Comment(0)
E
0

I've been also looking into promises in node.js recently. To date the when.js seems to be the way to go due to its speed and resource use, but the documentation on q.js gave me a lot better understanding. So use when.js but the q.js docs to understand the subject.

From the q.js readme on github:

If a function cannot return a value or throw an exception without blocking, it can return a promise instead. A promise is an object that represents the return value or the thrown exception that the function may eventually provide. A promise can also be used as a proxy for a remote object to overcome latency.

Elyssa answered 13/6, 2014 at 10:9 Comment(0)
C
0

Promise object represents the completion or failure of an asynchronous operation.

So in order to implement a promise, you need two parts:-

1.Creating Promise:

The promise constructor accepts a function called an executor that has 2 parameters resolve and reject.

function example(){
   return new Promise (function(resolve , reject){   //return promise object
      if(success){
         resolve('success');  //onFullfiled
      }else{
         reject('error');     //onRejected
      }
   })
}

2.Handling Promise:

Promise object has 3 methods to handle promise objects:-

1.Promise.prototype.catch(onRejected)

2.Promise.prototype.then(onFullfiled)

3.Promise.prototype.finally(onFullfiled,onRejected)

example.then((data) =>{
  //handles resolved data
  console.log(data); //prints success     
}).catch((err) => {
  //handles rejected error 
  console.log(err);  //prints error
})
Caisson answered 24/5, 2020 at 17:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.