¿Cuál es la diferencia entre BehaviorSubject y Observable?

Resuelto Kevin Mark asked hace 8 años • 14 respuestas

Estoy investigando los patrones de diseño de RxJS y no entiendo la diferencia entre BehaviorSubjecty Observable.

Según tengo entendido, BehaviorSubject puede contener un valor que puede cambiar. Se puede suscribir y los suscriptores pueden recibir valores actualizados. Ambos parecen tener exactamente el mismo propósito.

  1. ¿Cuándo se debe utilizar Observable frente a BehaviorSubject y viceversa?
  2. ¿Cuáles son los beneficios de utilizar BehaviorSubject en lugar de Observable y viceversa?
Kevin Mark avatar Sep 14 '16 22:09 Kevin Mark
Aceptado

BehaviorSubjectes una variante de Subject, un tipo Observableal que uno puede "suscribirse" como cualquier otro Observable.

Características de BehaviorSubject

  • Necesita un valor inicial ya que siempre debe devolver un valor al momento de la suscripción, incluso si no ha recibido el método.next()
  • Al suscribirse, devuelve el último valor del Asunto. Un Observable normal solo se activa cuando recibe el método.onNext()
  • En cualquier momento, se puede recuperar el último valor del Asunto en un No Observable usando el métodogetValue()

Características del tema

  • El sujeto es un "observador" además de ser un Observable; por lo tanto, también se pueden enviar valores a un Asunto y al mismo tiempo suscribirse a él.
  • Se puede obtener un valor de BehaviorSubject usando el métodoasObservable()

Ejemplo 1 usando BehaviorSubject

// BehaviorSubject.
// 'A' is an initial value. If there is a Subscription 
// after it, it would immediately get the value 'A'.

beSubject = new BehaviorSubject('a'); 

beSubject.next('b');

beSubject.subscribe(value => {
  console.log('Subscription received the value ', value);

  // Subscription received B. It would not happen
  // for an Observable or Subject by default.
});

beSubject.next('c');
// Subscription received C.

beSubject.next('d');
// Subscription received D.

Ejemplo 2 usando Asunto

// Subject.

subject = new Subject(); 

subject.next('b');

subject.subscribe(value => {
  console.log('Subscription received the value ', value);

  // Subscription won't receive anything at this point.
});

subject.next('c');
// Subscription received C.

subject.next('d');
// Subscription received D.

Se puede crear un Observable a partir de ambos Subjecty BehaviorSubject; Por ejemplo, subjectName.asObservable().

La única diferencia es que no se pueden enviar valores a un Observable usando el método next().

En Angular, se recomienda usarlo BehaviorSubjectpara transferir datos, ya que un Servicio a menudo se inicializa antes que un componente.

BehaviorSubject garantiza que el componente que consume el Servicio reciba los últimos datos actualizados, incluso si no hay nuevas actualizaciones, debido a la suscripción del componente al Servicio.

Shantanu Bhadoria avatar Oct 25 '2016 04:10 Shantanu Bhadoria

Observable: resultado diferente para cada observador

Una diferencia muy muy importante. Dado que Observable es solo una función, no tiene ningún estado, por lo que para cada nuevo Observador, ejecuta el código de creación observable una y otra vez. Esto resulta en:

El código se ejecuta para cada observador. Si es una llamada HTTP, se llama para cada observador.

Esto causa errores e ineficiencias importantes.

BehaviorSubject (o Asunto) almacena los detalles del observador, ejecuta el código solo una vez y proporciona el resultado a todos los observadores.

Ex:

JSBin: http://jsbin.com/qowulet/edit?js,console

// --- Observable ---
let randomNumGenerator1 = Rx.Observable.create(observer => {
   observer.next(Math.random());
});

let observer1 = randomNumGenerator1
      .subscribe(num => console.log('observer 1: '+ num));

let observer2 = randomNumGenerator1
      .subscribe(num => console.log('observer 2: '+ num));


// ------ BehaviorSubject/ Subject

let randomNumGenerator2 = new Rx.BehaviorSubject(0);
randomNumGenerator2.next(Math.random());

let observer1Subject = randomNumGenerator2
      .subscribe(num=> console.log('observer subject 1: '+ num));
      
let observer2Subject = randomNumGenerator2
      .subscribe(num=> console.log('observer subject 2: '+ num));
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.3/Rx.min.js"></script>
Expandir fragmento

Producción :

"observer 1: 0.7184075243594013"
"observer 2: 0.41271850211336103"
"observer subject 1: 0.8034263165479893"
"observer subject 2: 0.8034263165479893"

Observe cómo el uso Observable.createcreó resultados diferentes para cada observador, pero BehaviorSubjectdio el mismo resultado para todos los observadores. Esto es importante.


Otras diferencias resumidas.

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃         ObservableBehaviorSubject/Subject         ┃      
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫ 
┃ Is just a function, no state        ┃ Has state. Stores data in memory    ┃
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
┃ Code run for each observer          ┃ Same code run                       ┃
┃                                     ┃ only once for all observers         ┃
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
┃ Creates only ObservableCan create and also listen Observable┃
┃ ( data producer alone )             ┃ ( data producer and consumer )      ┃
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
┃ Usage: Simple Observable with only  ┃ Usage:                              ┃
┃ one Obeserver.                      ┃ * Store data and modify frequently  ┃
┃                                     ┃ * Multiple observers listen to data ┃
┃                                     ┃ * Proxy between Observable  and     ┃
┃                                     ┃   Observer                          ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
Vamshi avatar Jun 17 '2017 03:06 Vamshi

Tanto Observable como Sujeto son observables, lo que significa que un observador puede rastrearlos. Ambos tienen algunas características únicas. Hay 3 tipos de Sujetos, cada uno de los cuales también tiene características únicas.

Puede encontrar el ejemplo práctico aquí en stackblitz . (Debe verificar la consola para ver el resultado real)

ingrese la descripción de la imagen aquí

Observables

Son fríos: el código se ejecuta cuando tienen al menos un observador.

Crea una copia de los datos: Observable crea una copia de los datos para cada observador.

Unidireccional: el observador no puede asignar valor al observable (origen/maestro).

Subject

Están de moda: el código se ejecuta y el valor se transmite incluso si no hay un observador.

Comparte datos: los mismos datos se comparten entre todos los observadores.

bidireccional: el observador puede asignar valor al observable (origen/maestro).

Si utiliza el sujeto, se perderán todos los valores que se transmiten antes de la creación del observador. Así que aquí viene el asunto de la repetición.

ReplaySubject

Están de moda: el código se ejecuta y el valor se transmite incluso si no hay un observador.

Comparte datos: los mismos datos se comparten entre todos los observadores.

bidireccional: el observador puede asignar valor al observable (origen/maestro). más

Reproduzca la transmisión de mensajes: no importa cuándo se suscriba al asunto de la reproducción, recibirá todos los mensajes transmitidos.

En Asunto y ReplaySubject, no puede establecer el valor inicial en observable. Así que aquí viene BehavioralSubject ...

BehaviorSubject

Están de moda: el código se ejecuta y el valor se transmite incluso si no hay un observador.

Comparte datos: los mismos datos se comparten entre todos los observadores.

bidireccional: el observador puede asignar valor al observable (origen/maestro). más

Puede establecer un valor inicial: puede inicializar el observable con un valor predeterminado.

Kedar9444 avatar Nov 17 '2018 21:11 Kedar9444

El objeto Observable representa una colección basada en push.

Las interfaces Observer y Observable proporcionan un mecanismo generalizado para notificaciones push, también conocido como patrón de diseño de observador. El objeto Observable representa el objeto que envía notificaciones (el proveedor); el objeto Observador representa la clase que los recibe (el observador).

La clase Asunto hereda tanto Observable como Observador, en el sentido de que es a la vez observador y observable. Puede utilizar un asunto para suscribir a todos los observadores y luego suscribir el asunto a una fuente de datos de backend.

var subject = new Rx.Subject();

var subscription = subject.subscribe(
    function (x) { console.log('onNext: ' + x); },
    function (e) { console.log('onError: ' + e.message); },
    function () { console.log('onCompleted'); });

subject.onNext(1);
// => onNext: 1

subject.onNext(2);
// => onNext: 2

subject.onCompleted();
// => onCompleted

subscription.dispose();

Más información sobre https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/subjects.md

Md Ayub Ali Sarker avatar Sep 14 '2016 15:09 Md Ayub Ali Sarker