Reputation: 15734
I have a case where I want to do something once 10 async calls have completed
let i = 0;
let array = [];
do {
this.service.getSomething(i).subscribe(response => {
array[i] = response;
});
} while (i < 10);
// how can I know when the 10 async calls have completed?
How can I achieve this?
Upvotes: 2
Views: 397
Reputation: 7745
You can just count responses in separate variable, and check it before continue:
let i = 0;
let array = [];
var finishedCnt=0;
do {
this.service.getSomething(i).subsribe(response => {
array[i] = response;
finishedCnt++;
if(finishedCnt>=10) {
// all requests done, do something here
}
});
} while (i < 10);
Upvotes: 0
Reputation: 96959
This depends on whether you know the async operations (read Observables/Promises) beforehand or not.
For example if you can compose an array of Observables then the easiest way is to use forkJoin
:
let observables = [ ... ];
Observable.forkJoin(observables)
.subscribe(results => /* whatever */);
Otherwise, you can just mergeMap
them into a single chain a listen only to the complete
signal:
Observable.range(1, 10) // or whatever
.mergeMap(i => /* return Observable here */)
.subscribe(undefined, undefined, () => console.log('all done'));
Upvotes: 3
Reputation: 14707
'The Rx way' is to use forkJoin:
const requestParams = [0,1,2,3,4,5,6,7,8,9];
const requests = requestParams.map(i => this.service.getSomething(i));
Observable.forkJoin(requests).subscribe(reponseArray => alldone(responseArray));
Upvotes: 1
Reputation: 350821
You have to make your loop asynchronous, so that an iteration will only occur when the next response is available. Here is how you can do that:
(function loop(arr) {
if (arr.length >= 10) return alldone(array); // all done
this.service.getSomething(arr.length).subsribe(response => {
loop(array.concat(response)); // "recursive" call
});
})([]); // <--- pass empty array as argument to the loop function
function alldone(arr) {
console.log(arr);
}
The loop
function is immediately invoked with an empty array as argument. When you get the response, you call that function again, now with the extended array, ...etc. Once you have 10 responses, you call another function that will do something with the final array.
As you can see, I chose to eliminate the variable i
, since arr.length
has the same value.
Note that this kind of asynchronous processing can also be done with promises and some recent features like async
and await
. You might want to look into that. Here is an example
Upvotes: 0