Básicamente lo que quiero es algo como esto:
this.accounts.forEach(account=> { this.myService.sendMessage("hello", account).subscribe( success => { if(success) updateProgress... }) }
El problema de este código es que ejecuta todo de forma asíncrona sin esperar la petición anterior. Estaba buscando soluciones usando merge y flatMap pero estoy confundido. Me gustaría esperar a que se complete la solicitud antes de pasar a la siguiente iteración. Esto causa un problema si quiero agregar una barra de progreso.
Solución:
Basándome en las otras respuestas, esto es lo que se me ocurrió:
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"); });
La operación Concat secuenciará sus solicitudes:
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))
Aquí hay una técnica de muestra que puede funcionar para usted.
// 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);
Esto funciona mediante la creación de una serie de promesas que luego activan su suscripción a medida que finaliza cada una.