tengo los siguientes observables
callOne() { return new Observable(subscriber => { subscriber.next(true); setTimeout(() => { subscriber.complete(); }, 3000) }) } callTwo() { return new Observable(subscriber => { subscriber.next(false); setTimeout(() => { subscriber.complete(); }, 1000) }) }así que cuando llame suscríbete a ellos
this.callOne().subscribe(data => { console.log(data); }) this.callTwo().subscribe(data => { console.log(data); }) obtengo inmediatamente verdadero y falso impreso, incluso que configuré el método completo en setTimeout. Con eso digo que en x miliseconds no se pueden emitir nuevos valores después de la ejecución del método complete .
Cuando intento lo mismo pero esta vez los observables se convierten en promesas
let response1 = await this.callOne().toPromise(); console.log('response1', response1); let response2 = await this.callTwo().toPromise(); console.log('response2', response2);luego obtengo la impresión verdadera del callOne observable en 3000 milisegundos. Porqué es eso ?
¿Por qué cuando prometo que el método completo se tiene en cuenta con setTimeout pero con el observable no?
deberías cambiar algo en tu código. Tienes que ejecutar el siguiente método en setTimout. porque cuando ejecuta el siguiente método, los observables se activan y también se suscribe a un observable que invocará.
callOne() { return new Observable(subscriber => { setTimeout(() => { subscriber.next(true); // you can use like this subscriber.complete(); }, 6000) }) }Pero cuando usa esperar, funciona como entonces () y se invocará cuando todo esté completo.
Los observables y las promesas son cosas diferentes aunque puedan convertirse una en otra.
Lo que estás enfrentando es esperado. La promesa no se "resuelve" hasta que se completa el observable, por lo que solo después de completarse ejecuta la lógica, y así es como funcionan las promesas. Observables en ese sentido son diferentes.
De hecho, si no completa la transmisión, en la suscripción seguirá ejecutando el código, pero en la promesa, como la transmisión nunca se completa, no se ejecutará nada. Un error muy común es convertir en promesa los observables calientes de larga duración.
Me imagino que la promesa no se resuelve hasta la llamada subscriber.complete() . Dado que usó await , la ejecución no continuará hasta que se resuelva la promesa.
En realidad, este artículo explica que la promesa devuelta por toPromise() espera a que se complete el observable y luego devuelve el último valor: https://levelup.gitconnected.com/rxjs-operator-topromise-waits-for-your-observable-to -completo-e7a002f5dccb
Sin embargo, toPromise() está en desuso, por lo que no me molestaría en usarlo. En su lugar, puede envolver Observables en Promesas. Entonces puedes controlar exactamente cuándo se resuelven.
callOne() { const observable = new Observable((subscriber) => { subscriber.next(true); setTimeout(() => { subscriber.complete(); }, 3000); }); return new Promise((resolve) => { observable.subscribe((result) => resolve(result)); }); } Esta promesa se resolverá en la primera llamada de subscriber.next() , que creo que es lo que esperaba que sucediera.
Tenga en cuenta que los Observables pueden llamar a .next() repetidamente, pero las Promesas solo pueden resolverse una vez.