Sunday, October 20, 2013

Creating a Promise from a Node.js style function

Recently I had a situation where I needed to process a web request, write data into three databases and then send a response to the client i.e. success if all three writes succeeded and a failure if even one of them failed.

I wanted keep my code simple and not have to track state across three asynchronous calls. Promises seemed like the natural answer, however it turned out that the MongooseJS API do not return promises (currently).

Fortunately I discovered that the excellent Q library also supports denodefiying calls thus making a standard nodejs API call with call-backs fit into the Promise pattern.

Here’s an example

           /* req is the request passed in by express*/
            var objectA = new ModelA(req.body.objectA);  // instantiate objects from the requests 
            var objectB = new ModelB(req.body.objectB);
             var objectC = new ModelC(req.body.objectC);
           
               // create promise returning functions and bind the methods to the objects
            var saveObjectA = Q.nbind(objectA.save, object;
            var saveObjectB = Q.nbind(objectB.save, objectB);
            var saveObjectC = Q.nbind(objectC.save, objectC);

               Q.all ( [saveObjectA(), saveObjectB(), saveObjectC() ] )
                .then(function (arr) {
                 // The two callbacks for then deal with success and failure respectively
                // success returns an array of arrays. Each internal array lists the item written
     // and number of items written. This is essentially an array of parameters passed to the
    // callback in the original function i.e. before denodeifying

                   res.send(200, {objectAid: objectA.id });
            }, function (err){
                console.error(err);
                 res.send(500); // send a server error

            });

and that's it 

No comments:

Post a Comment