I have the following code:
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!!");
});
How does Q.all know that promises array has all the promises required by forEach loop? Sometimes, my Q.all runs before forEach. Please tell me where I am going wrong.
doSomething() is an asynchronous function which returns a promise.
I have the following code:
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!!");
});
How does Q.all know that promises array has all the promises required by forEach loop? Sometimes, my Q.all runs before forEach. Please tell me where I am going wrong.
doSomething() is an asynchronous function which returns a promise.
Share Improve this question asked Jun 10, 2015 at 12:39 skjindal93skjindal93 7342 gold badges17 silver badges36 bronze badges 1-
Can you give some practical example? You are ignoring
item
andindex
. Even if you get answers I am not sure you can directly use them for your actual problem – thefourtheye Commented Jun 10, 2015 at 12:51
2 Answers
Reset to default 6Q.all
cannot run before your forEach
, since forEach
is synchronous.
But you actually push things in the array after Q.all has been called. Your way of using promises is a bit awkward : no need to use a deffered in a promise!
Plus, you don't want to push the deffered itself but the promise that it holds, after rejecting or resolving it. See below for more info on how to "promisify" an asynchronous funtion.
Deffered are used to define promises out of symple callback-based asynchronous code. Since doSomething()
returns a promise (you are using .then()
), you could actually just do :
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!!");
});
Then promises will be directly populated with promises, without any delay.
EDIT : since you are asking about doSomething
not being promise-enabled, here is what you could do:
Let's say doSomething
takes as a parameter a callback to execute after some asynchronous task.
Then you could wrap doSomething
that way:
function doSomethingPromise(){
var defered = Q.defer();
doSomething(function(err,data){
if(err){
defered.reject(err);
}
else{
defered.resolve(data);
}
});
return defered.promise;
}
and then use doSomethingPromise()
as mentionned above, instead of doSomething
, since this one returns a promise.
The problem is that when Q.all
is executed, the promises
array is still empty. Deferred objects are being pushed onto promises
asynchronously, so Q.all()
will be executed before the promise from doSomething()
is resolved.