我有以下代码:
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的异步函数。
答案 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()
的承诺得到解决之前执行。