¿Cuándo usar asObservable () en rxjs?


84

Me pregunto cuál es el uso de asObservable:

Según los documentos:

Una secuencia observable que oculta la identidad de la secuencia fuente.

Pero, ¿por qué necesitarías ocultar la secuencia?

Respuestas:


187

Cuándo usar Subject.prototype.asObservable ()

El propósito de esto es evitar filtrar el "lado del observador" del Asunto fuera de una API. Básicamente para evitar una abstracción con fugas cuando no desea que las personas puedan "seguir" en el observable resultante.

Ejemplo

(NOTA: Esta no es realmente la forma en que debe convertir una fuente de datos como esta en un Observable, en su lugar, debe usar el new Observableconstructor, ver más abajo).

const myAPI = {
  getData: () => {
    const subject = new Subject();
    const source = new SomeWeirdDataSource();
    source.onMessage = (data) => subject.next({ type: 'message', data });
    source.onOtherMessage = (data) => subject.next({ type: 'othermessage', data });
    return subject.asObservable();
  }
};

Ahora, cuando alguien obtiene el resultado observable de myAPI.getData()no puede nextvalorar el resultado:

const result = myAPI.getData();
result.next('LOL hax!'); // throws an error because `next` doesn't exist

new Observable()Aunque normalmente deberías usar

En el ejemplo anterior, probablemente estamos creando algo que no pretendíamos. Para uno,getData() no es perezoso como la mayoría de los observables, creará la fuente de datos subyacente SomeWeirdDataSource(y presumiblemente algunos efectos secundarios) de inmediato. Esto también significa que si usted retryo repeatel observable resultante, no funcionará como cree.

Es mejor encapsular la creación de su fuente de datos dentro de su observable así:

const myAPI = {
  getData: () => return new Observable(subscriber => {
    const source = new SomeWeirdDataSource();
    source.onMessage = (data) => subscriber.next({ type: 'message', data });
    source.onOtherMessage = (data) => subscriber.next({ type: 'othermessage', data });
    return () => {
      // Even better, now we can tear down the data source for cancellation!
      source.destroy();
    };
  });
}

Con el código anterior, cualquier comportamiento, incluso hacer que sea "no perezoso", se puede componer sobre lo observable utilizando los operadores existentes de RxJS.


3
TX Ben ...
he

3
@Shardul ... te suscribirías al resultado:result.subscribe(value => doSomething(value))
Ben Lesh

2
@BenTaliadoros Sí, cada vez return subject.asObservable();sería un nuevo observable. Tendría una sola variable miembro de Subject, y onMessage / onOtherMessage se declararía en una condición o en la inicialización (no en todas las llamadas). He usado ese enfoque, pipe( filter() )basado en un parámetro proporcionado a la getData()función. The
Drenai

5
@BenLesh, ¿en su segunda muestra de código se subjectsupone que es subscriber?
Florin D

1
También me gustaría verificación aquí: deberían ser las subject.nextlíneas subscriber. Además, "si vuelve a intentarlo o repite el observable resultante, no funcionará como cree". ¿Puedes ser mas específico? ¿Quiere decir new SomeWeirdDataSource()que va a suceder cada vez que getDatase llame y que al envolverlo new Observablehace que la instanciación espere hasta una suscripción? Supongo que no veo cuándo llamarías getDatasin un, .subscribeasí que me falta el valor allí. Finalmente, ¿qué prevé que ocurra para "derribar la fuente de datos"? Gracias.
1252748

7

A Subjectpuede actuar como an observery an observable.

An Obervabletiene 2 métodos.

  • suscribir
  • darse de baja

Cada vez que se suscribe a un observable, obtiene un observerque tiene el siguiente , error y métodos completos .

Debería ocultar la secuencia porque no desea que la fuente de la transmisión esté disponible públicamente en todos los componentes. Puede consultar @BenLeshel ejemplo de, para el mismo.

PD: Cuando vine por primera vez a través de Reactive Javascript, no pude entender asObservable. Porque tenía que asegurarme de entender claramente los conceptos básicos y luego seguir adelante asObservable. :)

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.