【问题标题】:How does Q.all work in NodeJS?Q.all 在 NodeJS 中是如何工作的?
【发布时间】:2015-06-10 21:05:23
【问题描述】:

我有以下代码:

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 循环所需的所有 promise? 有时,我的 Q.all 在 forEach 之前运行。请告诉我哪里出错了。

doSomething() 是一个异步函数,它返回一个承诺。

【问题讨论】:

  • 你能举一些实际的例子吗?你忽略了itemindex。即使您得到答案,我也不确定您是否可以直接将它们用于您的实际问题

标签: javascript node.js promise q


【解决方案1】:

Q.all 无法在您的 forEach 之前运行,因为 forEach 是同步的。

但您实际上在调用 Q.all 之后 将内容推送到数组中。你使用 Promise 的方式有点尴尬:不需要在 Promise 中使用 defered!

另外,在拒绝或解决它之后,您不想推送延迟本身,而是推送它所持有的承诺。有关如何“承诺”异步函数的更多信息,请参见下文。

Deffered 用于从基于回调的简单异步代码中定义 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!!");
});

然后promise 将直接被promise 填充,没有任何延迟。

编辑:既然您询问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,因为这会返回一个承诺。

【讨论】:

  • 谢谢!如果我没有在 doSomething 中返回承诺怎么办?即 doSomething 只是一个异步函数,我想在 forEach 完成后运行 Q.all。
  • 我已经更新了我的答案以解释如何“承诺”非承诺异步函数。
  • 我认为@skjindal93 在这里过度简化了他的代码;甚至没有使用该项目的价值。不过,我认为这不是我们应该关注的问题。
  • 非常感谢 Tiesselune。
  • 嗨,这是一个很好的起点。我想知道,如何在 forEach 循环中捕获 doSomething() 中的错误。会是这样吗?:doSomething() .then(d => {return Q(true);}) .catch(e => {return Q(e);});
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-02
    • 2019-10-17
    • 1970-01-01
    • 2016-04-12
    • 2015-07-10
    • 2014-01-18
    相关资源
    最近更新 更多