【发布时间】:2014-04-04 16:20:59
【问题描述】:
我正在学习 q.js 并尝试在它的帮助下同时查询 3 个集合(避免回调地狱):
var Q = require('q')
var deferred = Q.defer();
users() 是 db.collection.find() 的包装器
var users = function (){
Auth.listUsers({role:'user'}, call)
return deferred.promise
}
call() 是导出承诺的简写
var call = function (err,data){
if (err) {
deferred.reject(err);
} else {
deferred.resolve(data);
}
}
loop()是主循环,获取光标并遍历条目
var loop = function (result) {
var list = []
var promises = [];
result.each(function (err,data){
if (err) {
deferred.reject(err);
} else {
deferred.resolve(data);
promises.push(deferred.promise)
console.log('promises_:', promises) // <- internal
}
})
console.log('promises:', promises) // <- external
return Q.all(promises)
}
代码:
users()
.then(loop)
.then(function(ful){
console.log('ful:', ful); // <- here should come the queries to other collections
})
最后的控制台记录结果:
promises: [] //external is empty
ful: []
promises_: [ [object Object] ] // internal is being filled
promises_: [ [object Object], [object Object] ]
如您所见,.each 的回调执行晚于将 Promise 推送到数组。
我相信它可以通过使用result.toArray() 而不是.each 来完成,但是如何在.each 循环的帮助下完成呢?
result 是一个游标,由 mongodb 驱动程序在 db.collection.find() 调用 (http://mongodb.github.io/node-mongodb-native/api-generated/collection.html#find) 后返回。
【问题讨论】:
-
你从哪里得到
each()?你用 Javascript 函数forEach()试过了吗?它可能对你更有效。另外,我不确定我是否遵循了result.each()的function (err,data)调用,您的each调用是否出错? -
你从哪里得到每个
deferred变量? -
添加了询问的信息。
-
知道了,谢谢 - 我不是 mongo 人,但如果我正确地遵循这一点,我认为您的一般问题是
.each()方法正在异步执行,但不是一部分你的承诺计划。您可能想要使用Q.ninvoke、Q.denodeify或一些类似的策略,以便each()返回一个承诺。另外,我知道您显然在删除一些代码,但正如所写,您只有一个deferred正在操作。在你的循环中,你只是用相同承诺的多个副本填充数组,这在你正在解决的前一行中。 -
你说得对,
.each()是异步的。无法理解Q函数(.fcall、.ncall等)。你能推荐一个关于这个库的好教程或详细手册吗?我对它的主页不满意。
标签: node.js promise deferred q