En mi proyecto actual, encontré la función que se indica a continuación:
translateString(stringToTranslate: string) { let translation; this.translateService.get(stringToTranslate).subscribe( data => { translation = data; }); return translation; }Parece ridículo ya que el método TranslateService.get() devuelve un Observable en todos los casos, pero en realidad funciona de alguna manera (la cadena traducida se devuelve inmediatamente)... ¿Cuál es la explicación de este comportamiento? ¿No debería agregarse la función de devolución de llamada a la pila de ejecución y ejecutarse más tarde?
El hecho de que esté utilizando Observables no significa automáticamente que todo se llamará en una devolución de llamada de JavaScript separada.
De hecho, la mayoría de los Observables y operadores predeterminados emiten todo de inmediato y no usan ningún Programador de forma predeterminada. Por ejemplo, eche un vistazo a este https://github.com/ReactiveX/rxjs/blob/master/src/observable/ArrayObservable.ts#L118
Obviamente, esto es diferente cuando se usa, por ejemplo, el operador delay() que necesita programar la ejecución, consulte https://github.com/ReactiveX/rxjs/blob/master/src/operator/delay.ts#L52 .
Por ejemplo, considere el siguiente ejemplo:
Observable.from([1,2,3], Scheduler.async) .subscribe(val => console.log(val)); Observable.from(['a','b','c'], Scheduler.async) .subscribe(val => console.log(val));Que programa cada emisión en otra devolución de llamada JS:
1 "a" 2 "b" 3 "c"Ver demostración: https://jsbin.com/zalugev/3/edit?js,console
Si no configura ningún programador, todo se emitirá de inmediato (sincrónicamente):
Observable.from([1,2,3]) .subscribe(val => console.log(val)); Observable.from(['a','b','c']) .subscribe(val => console.log(val));Que imprime lo siguiente:
1 2 3 "a" "b" "c"Ver demostración: https://jsbin.com/zalugev/4/edit?js,console
Con respecto a su pregunta, no debe confiar en la biblioteca de terceros para emitir valores de inmediato porque nunca se sabe cuándo cambia esto y su código se romperá.
No estoy seguro de si ese podría ser el problema aquí, pero algunos observables emiten sincrónicamente. Este es el caso de Observable.of por ejemplo creo. Si translateService es síncrono, inmediatamente se llamará a su observador de suscripción y se completará su valor de translation .
Puede influir en el momento de la emisión mediante el uso de programadores, que es probablemente la parte menos documentada de rxjs. Eche un vistazo a https://github.com/ReactiveX/rxjs/blob/master/MIGRATION.md , sección Schedulers Renamed
Un Observable es esencialmente solo un contenedor para las devoluciones de onSuccess() , onError() y onComplete() . Si las funciones que se ejecutan son sincrónicas, un Observable también lo será. Esta es la funcionalidad principal de un Observable (el resto es solo limpieza):
export class Observable { constructor(subscribe) {} subscribe(observerOrNext, error, complete) {} // callbacks } Observable.create = (subscribe) => { return new Observable(subscribe); // dot-chaining }Mira este video donde André Staltz construye observables desde cero.