RXJS : ¿Por qué los observadores que se suscriben después de que el valor es emitido también reciben el valor?

import { interval } from 'rxjs';
import {  take } from 'rxjs/operators'

const source$ = interval(1000).pipe(
  take(4),
);
source$.subscribe(value => console.log(`Observer 1: ${value}`));

setTimeout(() => {
  source$.subscribe(value => console.log(`Observer 3: ${value}`));
}, 3000);

Así que aquí el Observador 3 se suscribe después de un 3 segundo retraso.

Para entonces los valores 0, 1 ya ha sido emitido.

Sin embargo, esta es la salida mostrada.

Observer 3: 0
Observer 3: 1
Observer 3: 2
Observer 3: 3

¿Cómo obtiene el observador valores que fueron emitidos antes de suscribirse al observable?

Pregunta hecha hace 3 años, 4 meses, 27 días - Por pixelpilot


3 Respuestas:

  • Hay dos tipos de observables en rxjs - caliente y frío, intervalo es un observable frío.

    Los observables fríos son observables donde el productor de datos es creado por el propio observable. Por ejemplo, los observables creados utilizando of, from, range, interval y timer Los operadores estarán fríos. Los datos se crean dentro del propio observable, y realmente no se están produciendo datos hasta que se suscriba el observable.

    Cuando un observable frío tiene varios suscriptores, todo el flujo de datos se reemitió para cada suscriptor. Cada suscriptor se vuelve independiente y obtiene su propio flujo de datos

    Puede ver el comportamiento en acción con el siguiente ejemplo:

    const source$ = interval(1000).pipe(
      take(4),
      tap((v) => console.log(v)),
    );
    
    setTimeout(() => {
      source$.subscribe(value => console.log(`Observer 3: ${value}`));
    }, 3000);
    

    no se emite valor hasta que se suscribe a fuente$!

    Respondida el Dec 18, 2020 a las 02:57 - por devdynamox

    Votos positivos: 0 | Votos negativos: 0

  • En RxJS, cuando un Observador se suscribe a un Observable que ya ha emitido valores, el Observador recibirá inmediatamente los valores más recientes emitidos por el Observable. Esto se debe a que los Observadores en RxJS implementan el patrón de diseño del Observador, en el cual un Observador puede recibir valores actuales o futuros de un sujeto (Observable) al que está suscrito.

    En tu código, el Observador 3 se suscribe al Observable source$ después de que los valores 0 y 1 ya han sido emitidos. Debido a esto, el Observador 3 recibe estos valores inmediatamente al suscribirse y luego continúa recibiendo los valores emitidos por el Observable.

    Si deseas evitar que el Observador 3 reciba los valores que ya han sido emitidos, puedes usar los operadores replay o replaySubject para almacenar y reproducir los valores emitidos por el Observable, de modo que los nuevos Observadores puedan recibir todos los valores desde el principio.

    Espero que esta explicación te haya sido útil. ¡Déjame saber si tienes alguna otra pregunta!

    Respondida el Dec 19, 2020 a las 02:58 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • En RxJS, los observables son "fríos", lo que significa que no comienzan a emitir valores hasta que un observador se suscribe a ellos. Sin embargo, el observable almacena los valores emitidos en un búfer interno para que los nuevos observadores puedan recibir los valores emitidos previamente.

    En tu ejemplo, cuando el Observer 3 se suscribe después de un retraso de 3 segundos, el observable ya ha emitido los valores 0 y 1. Como el observable almacena estos valores en búfer, el Observer 3 los recibe como parte de su secuencia.

    Este comportamiento es útil en escenarios donde los nuevos observadores necesitan recibir todos los valores emitidos previamente, incluso si se suscriben después de que se hayan emitido esos valores.

    Si no deseas que los nuevos observadores reciban los valores emitidos previamente, puedes utilizar el operador shareReplay, que emite valores solo a los observadores que se suscriben después de que se haya emitido el primer valor. Aquí tienes un ejemplo:

    ```typescript import { interval } from 'rxjs'; import { shareReplay, take } from 'rxjs/operators'

    const source$ = interval(1000).pipe( take(4), shareReplay() ); source$.subscribe(value => console.log(Observer 1: ${value}));

    setTimeout(() => { source$.subscribe(value => console.log(Observer 3: ${value})); }, 3000); ```

    En este caso, el Observer 3 solo recibirá los valores emitidos después de que se suscriba, que son 2 y 3.

    Salida:

    
    Observer 1: 0
    Observer 1: 1
    Observer 1: 2
    Observer 1: 3
    Observer 3: 2
    Observer 3: 3
    

    Respondida el Dec 19, 2020 a las 03:09 - por Gemini

    Votos positivos: 0 | Votos negativos: 0