节点 q 承诺递归

Posted

技术标签:

【中文标题】节点 q 承诺递归【英文标题】:node q promise recursion 【发布时间】:2014-03-23 15:36:17 【问题描述】:

我有一个返回随机学生的异步函数。现在我想要一个返回两个独特学生的函数——我的问题的根源。

    getTwoRandom = function(req) 
        var deferred = Q.defer();

        Q.all([
            Student.getRandom(req), 
            Student.getRandom(req)
            ])
        .then(function(students)
            if(students[0]._id !== students[1]._id)  //check unique
                deferred.resolve(students);
             else 
                //students are the same so try again... this breaks
                return getTwoRandom(req);
            
        );

        return deferred.promise;
    ;

然后再往下我有这样的东西:

getTwoRandom(req).then(function(students) 
     //do what I want...
);

问题是当我执行return getTwoRandom(req); 时,.then() 函数不会触发...这是否返回了 .then() 未使用的不同承诺?

【问题讨论】:

【参考方案1】:

你有点过于复杂了:)

你可以这样做:

getTwoRandom = function(req) 
    return Q.all([
        Student.getRandom(req), 
        Student.getRandom(req)
    ]).then(function(students) 
        if(students[0]._id !== students[1]._id) 
            return students;
         else 
            return getTwoRandom(req);
        
    );
;

现在,为什么会这样? Q.all 的结果总是一个新的 promise(不需要创建一个新的 deferred)。无论您返回什么值 (ike students) 都将包含在这个新的承诺中。相反,如果返回一个实际的承诺(如getTwoRandom(req)),那么该承诺将被返回。这听起来像你想做的事。

【讨论】:

困惑的 b/c 这不是返回一个让我以后使用的承诺......?后续代码会是什么样子? 什么意思?它绝对返回一个承诺。就像我上面描述的那样,Q.all 返回一个承诺,我们正在返回它。 再往下,你会完全按照你自己描述的那样使用它。 它说“无法调用未定义的方法'then'” 可能你忘记了函数开头的“return”。

以上是关于节点 q 承诺递归的主要内容,如果未能解决你的问题,请参考以下文章

Mongoose.create + Q 将 mongoose 承诺转换为 Q 承诺

猫鼬承诺和Q承诺

像在 Q 中定义空的 Bluebird 承诺

使用承诺和递归迭代文件目录

猫鼬和 q 承诺

nodejs 中的异步和 Q 承诺