I'm using Restangular to do several simultaneous calls to the server. Restangular returns promises for each action, each one of them needs to do something with its specific return, and once all 3 are complete and their .then
functions have completed, I need to perform another function.
Is this the right way to do promises in this instance?
var a, b, c;
a = service1.getList(...).then(function A(data) { do something; $log.debug('a'); return 'a';});
b = service2.getList(...).then(function B(data) { do something; $log.debug('b'); return 'b';});
c = service3.getList(...).then(function C(data) { do something; $log.debug('c'); return 'c';});
$q.all([a,b,c]).then(function wrapUp(values) { $log.debug(values); do something after functions A, B,and C above have finished;}
I don't know if $q.all() will run at the very end of A,B, and C, or if it could race in front of the last function. Will wrapUp() ALWAYS be called last?
Note the A,B, and C are the functions called after promises a,b, and c are completed.
The values array passed to wrapUp appears to be the the return values from A,B and C. However, in my console, functions A logs 10 times, and then function B logs 10 times, then function C and function wrapUp are both logging 10 times (alternating).
The 10x logging seems like something is broken....., and the feared race condition appears to be a possibility....
Can someone explain what is going on here?
Is this the right way to do promises in this instance?
Yes, it is.
The 10x logging seems like something is broken....., and the feared race condition appears to be a possibility....
Can someone explain what is going on here?
It's actually not broken. Like you suggest $q.all
waits for all promises to complete.
In:
$q.all([a,b,c,d]).then(function(){
// yes, this only runs after all of the promises fulfilled
});
Here is what happens:
You have a loop that runs 10 times:
$q.all
for that instance of a,b,c for the a (already resolved) the b (already resolved) and now the c - fulfilled.$q.all
for that instance of a,b,c for the a (already resolved) the b (already resolved) and now the c - fulfilled.And so on.
The only guarantee you have is that inside the loop that instance of $q.all([a,b,c]
will fulfill after its local a,b and c. Nothing else, nothing more.
If you want to hook on the aggregate promise of all the return values, you can of course perform a $q.all
on all ten of them.