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]--+
我使用外部variablesuupr
和cupr
来存储来自第一个调用的数据。
所以我有两个问题:
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
而不是显式)