javascript - Chaining Asynchronous Functions Node.js bluebird mongoskin -


i have been reading many posts on how chain asynchronous functions can't seem right!

as title indicates. trying chain mongoskin database calls together, can gather information in chunks , send accumulated result in response.

i have object user :

var user = {        username: 'someusername',        accounts: [{name: 'account_1'}, {name: 'account_2'}]    } 

for each of accounts need gather data , send accumulated data in response. using following loop iterate on accounts:

var promise = require('bluebird'); var db = require('mongoskin').db('mongodb://localhost/somedb');  for(var x in user.accounts){    //fetch account data    user.accounts[x].accountdata = fetchaccountdata(user.accounts[x].name); }  //finally send collected response response.send(user); 

and function fetchaccountdata looks following:

function fetchaccountdata(screen_id){    db.collection('master')      .aggregate([         {$match: {screen_id: screen_id}}       ], function(err, res){            if(err)               return null;            else{               console.log('done', screen_id);               return res;           }      });  } 

how can chain have following algorithm:

 start:       each account:            fetchdataforaccount       finally:            send response  

your algorithm can achieved using following code:

var promise = require('bluebird'); var mongo = require('mongoskin'), db;  promise.promisifyall(mongo.collection.prototype);  db = mongo.db('mongodb://localhost/somedb');  promise.all(user.accounts.map(function(acct) {   return fetchaccountdata(acct.name).then(function(data) {     acct.accountdata = data;   }); })) .then(function() {   response.send(user); }) .catch(function(err) {   // handle error });  function fetchaccountdata(screen_id){    return db      .collection('master')      .aggregateasync([         {$match: {screen_id: screen_id}}       ]); } 

edit: here's breakdown of code

the first thing need ensure aggregate returns promise instead of using continuation (e.g. callback). can using bluebird's amazing promisification abilities :) here use on mongo.collection.prototype when collection() called return promise-capable collection instance. have fetchaccountdata return promise returned aggregateasync client has way of knowing when promise resolved.

next, map on each account in accounts , return promise fulfilled once account data fetched and has been assigned account object. use promise.all return promise fulfilled "when items in array fulfilled" (from docs).

finally, have use then() "wait" until promise returned has resolved, , send response complete user object.


Comments

Popular posts from this blog

facebook - android ACTION_SEND to share with specific application only -

python - Creating a new virtualenv gives a permissions error -

javascript - cocos2d-js draw circle not instantly -