Reputation: 7208
Basically what I want is something like this:
this.accounts.forEach(account=> {
this.myService.sendMessage("hello", account).subscribe(
success => {
if(success)
updateProgress...
})
}
The problem with this code is that it executes everything asynchronously without waiting for the previous request. I was looking at solutions using merge and flatMap but I'm confused. I'd like to wait on the request completion before moving to next iteration. This causes a problem if I want to add a progress bar.
Solution:
Basing on the other answers this is what I've come up with:
let requestList = this.accounts.map((account, index) => {
return this.myService.sendMessage("hello", account).map(success => {
if (success)
{
// Update progress here
}
return success;
});
});
Observable.concat(...requestList).subscribe(null, null, () => {
console.log("Complete");
});
Upvotes: 0
Views: 1661
Reputation: 2645
Here is a sample technique which may work for you.
// create an array of promise/resolves that will sequence the calls
let resolveArray: Array<(value: boolean) => void> = new Array[this.accounts.length];
this.accounts.forEach((account, index) => {
new Promise<boolean>((resolve, reject) => {
// add the promise to the array.
resolveArray[index] = resolve;
}).then(result => {
this.myService.sendMessage("hello", account).subscribe(
success => {
if(success)
// updateProgress...
// when finished, resolve the next promise in the array
if (index < this.resolveArray.length) {
this.resolveArray[index + 1](true);
}
})
});
});
// resolve the first promise to start the resolve sequence.
resolveArray[0](true);
This works by creating an array of promises that then trigger your subscription as each one finished.
Upvotes: 1
Reputation: 17879
Concat operation will sequence your requests:
let accounts = ['1', '2', '3', '4' ];
var i = 8000;
let obsList$= accounts.map(x=> {
i = i - 1000;
return Rx.Observable.of(x).delay(i);
});
Rx.Observable.concat(...obsList$)
.subscribe(x=>console.log(x))
Upvotes: 2