Q.all如何在NodeJS中工作?

时间:2015-06-10 12:39:57

标签: javascript node.js promise q

我有以下代码:

var a = [1,2,3,4,5];
var promises = [];
a.forEach(function(item,index){
    var deferred = Q.defer();
    doSomething().then(function(){
        deferred.resolve(true);
        promises.push(deferred);
    });
});

Q.all(promises).then(function(data){
    console.log("something!!");
});

Q.all如何知道promises数组具有forEach循环所需的所有承诺? 有时候,我的Q.all会在forEach之前运行。请告诉我哪里出错了。

doSomething()是一个返回promise的异步函数。

2 个答案:

答案 0 :(得分:6)

Q.all无法在forEach之前投放,因为forEach是同步的。

但实际上,在调用 Q.all之后,你实际上会在数组中推送内容。你使用promises的方式有点尴尬:不需要在promise中使用deffered!

另外,在拒绝或解决它之后,你不想推动自己的违背,而是它所拥有的承诺。有关如何“宣传”异步功能的更多信息,请参见下文。

Deffered用于定义基于symple回调的异步代码中的promise。由于doSomething()会返回一个承诺(您正在使用.then()),您实际上可以这样做:

var a = [1,2,3,4,5];
var promises = [];
a.forEach(function(item,index){
    var promise = doSomething().then(function(data){
        return Q(true);
    });
    promises.push(promise);
});

Q.all(promises).then(function(data){
    console.log("something!!");
});

然后承诺将直接填充承诺,不会有任何延迟。

编辑:既然你问doSomething没有启用承诺,那么你可以做以下事情:

假设doSomething将一个异步任务后执行的回调作为参数。

然后你可以这样包裹doSomething

function doSomethingPromise(){
    var defered = Q.defer();
    doSomething(function(err,data){
       if(err){
           defered.reject(err);
       }
       else{
           defered.resolve(data);
       }
    });
    return defered.promise;
}

然后使用上面提到的doSomethingPromise()而不是doSomething,因为这会返回一个承诺。

答案 1 :(得分:2)

问题是当执行Q.all时,promises数组仍为空。延迟对象被异步推送到promises,因此Q.all()将在doSomething()的承诺得到解决之前执行。