Node pattern for promises

I have a node issue. I want to call a Data Access Object and possibly other within it and once completed render a Jade template

Something like :

 provider1.getData(args, function(error, results) {

   /* do something with each result element */
   for(int i = 0l i < results.length; i++) {
     provider2.getData(args, function(error, items) {

        store.push(items);
     });
   }
 });
 /* Here I want to ensure that the above operations are complete */
 result.render( .... , {
   data:store
 });

Basically, I want to ensure that the data retrieval completes before I render a template with the data. At the moment, the variable store is not populated when the render occurs. I have looked at promises which looks promising. Does anyone have a neat solution for converting my code example into a synchronous structure ?

Answers


You should try using async library.

provider1.getData(args, function(error, results) {

   /* do something with each result element */
   async.each(results,
                       function(result, cb) { // called for each item in results
                           provider2.getData(args, function(error, items) {

                                  store.push(items);
                                  cb(error);
                            });
                       },
                       // final callback
                       function (err) {
                           if (!err) {
                             /* Here I want to ensure that the above operations are complete */
                              result.render( .... , {
                                     data:store
                               });
                           }
                       }
                    );

}

Here is a promises answer (assuming Bluebird). I think it's a lot cleaner:

// convert to promise interface, it's possible to do this on a single method basis
// or an API basis, it depends on your case - it's also _very_ fast. 
Promise.promisifyAll(Object.getPrototypeOf(provider1.prototype)); 
Promise.promisifyAll(Object.getPrototypeOf(provider2.prototype));

//note the async suffix is added by promisification.
provider1.getDataAsync(args).then(function(results) {
   return Promise.map(results,provider2.getDataAsync.bind(provider2));
}).then(function(results){
    //results array here, everything is done and ready,
});

As always with promises, if you have an error you can simply throw.


Need Your Help

MSMQ messages bound for clustered MSMQ instance get stuck in outgoing queues

msmq message-queue nservicebus cluster-computing msdtc

We have clustered MSMQ for a set of NServiceBus services, and everything runs great until it doesn't. Outgoing queues on one server start filling up, and pretty soon the whole system is hung.

LineChart segments in Flex

flex charts linechart

I'm doing some line charts in my Flex application, and I need to draw segments of those line chart in different color. Does anyone have an idea how this could be achieved? For instance, if I have a...