Q.jsvariables并行传递

在实现承诺时得到了这样的代码:

var MongoClient = require('mongodb').MongoClient MongoClient.connect(db_uri, function(err, db) { if(err) throw err; var ccoll = db.collection('cdata'); app.locals.dbstore = db; } var json= {} //Auth is a wrapped mongo collection var Auth = app.locals.Auth; var coll = app.locals.dbstore.collection('data'); var ucoll = app.locals.dbstore.collection('udata'); var ccoll = app.locals.dbstore.collection('cdata'); var Q = require('q'); //testing with certain _id in database var _id = require('mongodb').ObjectID('530ede30ae797394160a6856'); //Auth.getUserById = collection.findOne() var getUser = Q.nbind(Auth.getUserById, Auth); //getUserInfo gives a detailed information about each user var getUserInfo = Q.nbind(ucoll.findOne, ucoll); var getUserData = Q.nbind(ccoll.findOne, ccoll); //"upr" is a group of users //getUsers gives me a list of users, belonging to this group var getUsers = Q.nbind(ucoll.find, ucoll); //Auth.getUserById = collection.find() var listUsers = Q.nbind(Auth.listUsers, Auth); var uupr = {} var cupr = {} getUserInfo({_id:_id}) .then(function(entry){ console.log('entry:', entry); uupr = entry; var queue = [getUsers({upr:entry.name}), getUserData({_id:entry._id})] return Q.all(queue); } ) .then(function(array2){ console.log('array2:', array2); cupr = array2[1] var cursor = array2[0] var cfill = Q.nbind(cursor.toArray, cursor); return cfill(); } ) .then(function(data){ json = {data:data, uupr:uupr, cupr:cupr} console.log('json:', json) res.render('test', {json : JSON.stringify(json)}) } ) 

它的工作可以用图来描述:

 getUserInfo()==>(entry)--+-->getUsers()=====>array2[0]--+-->populate user list===>data--->render | | +-->getUserData()==>array2[1]--+ 

我使用外部variablesuuprcupr来存储来自第一个调用的数据。

所以我有两个问题:

1)避免使用外部variables。

2)重新排列代码以获得替代stream程图。

  getUserInfo()==>(entry)--+-->getUsers()==>usersList-->populate user list==>usersData-+->render | | +-->getUserData()====>uprData-------------------------------+ 

任何意见表示赞赏

尝试一下这个伪代码:

 getUserInfo().then(function(userInfo) { return Q.all([ userInfo, getUsers(... userInfo ...).then(convert to array), getUserData(... userInfo ...) ]) }).spread(function(userInfo, usersArray, userData) { res.render(...) }, function(err) { handle the error }).done() 

你可以简单地嵌套它们:

 getUserInfo({_id:_id}) .then(function(entry){ console.log('entry:', entry); return Q.all([ getUsers({upr:entry.name}), getUserData({_id:entry._id}) ]); .spread(function(cursor, cupr) { console.log('array2:', [cursor, cupr]); return Q.ninvoke(cursor, "toArray") .then(function(data){ return {data:data, uupr:entry, cupr:cupr}; }); }); }).then(function(json) { console.log('json:', json) res.render('test', {json: JSON.stringify(json)}) }); 

现在,让toArray不要等待getUserData结果,只需要并行执行:

 getUserInfo({_id:_id}) .then(function(entry){ console.log('entry:', entry); return Q.all([ getUsers({upr:entry.name}).invoke("toArray"), getUserData({_id:entry._id}) ]); .spread(function(data, cupr) { return {data:data, uupr:entry, cupr:cupr}; }); }).then(function(json) { console.log('json:', json) res.render('test', {json: JSON.stringify(json)}) }); 

then使用invoke而不是显式)