Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/33.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
node.js_Node.js_Promise_Deferred_Q - Fatal编程技术网

node.js

node.js,node.js,promise,deferred,q,Node.js,Promise,Deferred,Q,我正在学习q.js,并尝试在其帮助下同时查询3个集合(避免回调地狱): users()是db.collection.find()的包装 call()是导出承诺的缩写 var call = function (err,data){ if (err) { deferred.reject(err); } else { deferred.resolve(data); } } loop()是主循环,它通过条目获取光标和循环 var loop = f

我正在学习q.js,并尝试在其帮助下同时查询3个集合(避免回调地狱):

users()是db.collection.find()的包装

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)
}
正如您所看到的,
。每个
的回调都是在将承诺推送到数组之后执行的。 我相信可以使用
result.toArray()
而不是
。each
,但是如何借助
。each
循环来实现呢

结果是一个游标,由mongodb驱动程序在db.collection.find()调用()之后返回

call()
是导出承诺的缩写

var call = function (err,data){
    if (err) {
        deferred.reject(err);
    } else {
        deferred.resolve(data);
    }
}
那不行!您需要为您想要的每个承诺创建一个新的延迟。然而,你!相反,使用


如您所见,.each的回调在将承诺推送到数组之后执行。我相信它可以通过使用result.toArray()而不是.each来实现,但是如何在.each循环的帮助下实现呢

它不能,除非您事先知道调用每个的频率以及需要创建多少承诺
Q.all
在这里有点无用,因为承诺不是一次创建的,而是并行执行它们的任务,而是一个流

您确实应该在这里使用
toArray
,以获得一个用于解析承诺的回调

嗯,有一种方法,但是它比
toArray
更丑陋,效率更低。你可以有一个延迟的问题,它将一直等待,并且只能通过承诺流的其余部分来解决

function loop(result) {
    var deferred = Q.defer();
    result.each(function (err,data){
        if (err) {
            deferred.reject(err);
        } else if (data == null) {
            deferred.resolve([]); // end of the stream
        } else {
            var nextDeferred = Q.defer();
            deferred.resolve(nextDeferred.promise.then(function(rest) {
                return [data].concat(rest);
            }));
            deferred = nextDeferred;
        }
    })
    return deferred.promise;
}

您从哪里获得
each()
?您是否使用Javascript函数
forEach()
尝试过它?它可能对你更有效。另外,我不确定我是否遵循了
结果。每个()调用都有
函数(err,data)
你的
调用都有错误吗?你从哪里得到每个
延迟的
变量?添加了所需的信息。明白了,谢谢-我不是mongo人,但如果我正确地遵循了这一点,我认为您的一般问题是
.each()
方法是异步执行的,但它不是promise方案的一部分。您可能希望使用
Q.ninvoke
Q.denodeify
,或一些类似的策略,以便
each()
返回承诺。另外,我知道您显然正在剥离一些代码,但正如所写的,您只有一个
延迟的
。在循环中,您只是用同一承诺的多个副本填充数组,这在您要解析的前一行中。您是对的,
。each()
是异步的。无法理解
Q
函数(
.fcall
.ncall
等)。你能推荐一本关于这个库的好教程或详细手册吗?我对它的主页不满意。谢谢你的关注。我将尝试
.toArray()
。是否可以同步执行
someArray.forEach(callbackFunction())
?在mongodb驱动程序中
。每个()都记录为异步。是的!=<代码>每个
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] ]
var deferred = Q.defer();
…
deferred.resolve(…);
…
deferred.resolve(…);
function loop(result) {
    var deferred = Q.defer();
    result.each(function (err,data){
        if (err) {
            deferred.reject(err);
        } else if (data == null) {
            deferred.resolve([]); // end of the stream
        } else {
            var nextDeferred = Q.defer();
            deferred.resolve(nextDeferred.promise.then(function(rest) {
                return [data].concat(rest);
            }));
            deferred = nextDeferred;
        }
    })
    return deferred.promise;
}