Usando Angular y la biblioteca RxJS.
Tengo un método simple:
method(){ const data = this.data; const moreData = this.moreData; this.anotherMethodOne(data) this.anotherMethodTwo(moreData) } Como puede ver, estoy llamando a otros dos métodos. anotherMethodOne() debe ejecutarse antes anotherMethodTwo() , y lo es.
Dentro anotherMethodOne() tengo un .subscribe :
anotherMethodOne(data) { <!-- at this point it jumps out of this method and continues to proceed in the parent method, but returns later --> this.service.getService(id).subscribe(res => { res } } Tan pronto como mi depurador golpea la llamada .subscribe, vuelve al method() y procede a ejecutar this.anotherMethodTwo(moreData) . Luego regresa a this.anotherMethodOne(data) para finalmente completar .subscribe ; sin embargo, en este momento ya es demasiado tarde.
Necesito asegurarme de que this.anotherMethodOne(data) se complete por completo antes de que se this.anotherMethodTwo(moreData) o asegurarme de que .subscribe se ejecute antes de continuar.
Empecé a mirar switchMap y concat en la biblioteca RxJS, pero no estaba seguro de cómo se implementaría en mi caso.
No puede garantizar que un observable se haya emitido antes de proceder con su valor emitido. Por lo tanto, debe devolver el observable de los métodos y suscribirse donde se requiere su valor.
Para observables dependiendo de las emisiones de otros observables, puede usar un operador de mapeo de orden superior como switchMap . Más info sobre ellos aquí .
method(){ const data = this.data; const moreData = this.moreData; this.anotherMethodOne(data).pipe( switchMap((someValue) => this.anotherMethodTwo(moreData) ) ).subscribe({ // callbacks }); } anotherMethodOne(data): Observable<any> { return this.http.get('url'); } anotherMethodTwo(moreData): Observable<any> { return this.http.get('url'); }Cuando se trata de funciones asincrónicas, debe permanecer con el enfoque reactivo y no intentar determinar cuándo finalizó un determinado código, sino simplemente esperar a que finalice y luego invocar la devolución de llamada o el controlador responsable posteriormente. Piensa sobre esto. ¿Qué es la suscripción que nunca devuelve nada? ¿Está bien? ¿Qué sucede si se tarda mucho tiempo en devolver algo? ¿También está bien?
Pero para solucionar el problema en cuestión, simplemente mueva anotherMethodTwo a la suscripción. Luego, cuando se devuelve algo, se ejecuta anotherMethodTwo .
method(){ const data = this.data; const moreData = this.moreData; this.anotherMethodOne(data) } anotherMethodOne(data) { this.service.getService(id).subscribe(res => { console.log(res) this.anotherMethodTwo(moreData) } }Seguir este camino sería similar al infierno de devolución de llamada asíncrona, cuyo estilo de anidamiento no se recomienda, pero lo hará por ahora.