Comportamiento ¿Sujeto vs Observable?

757
Kevin Mark 2016-09-15 05:14.

Estoy investigando los patrones de Angular RxJ y no entiendo la diferencia entre a BehaviorSubjecty an Observable.

Según tengo entendido, a BehaviorSubjectes un valor que puede cambiar con el tiempo (se puede suscribir y los suscriptores pueden recibir resultados actualizados). Este parece ser exactamente el mismo propósito de un Observable.

¿Cuándo Observableusarías un vs a BehaviorSubject? ¿Hay beneficios de usar un BehaviorSubjectover an Observableo viceversa?

10 answers

1069
Shantanu Bhadoria 2016-10-25 18:53.

BehaviorSubject es un tipo de sujeto, un sujeto es un tipo especial de observable, por lo que puede suscribirse a mensajes como cualquier otro observable. Las características únicas de BehaviorSubject son:

  • Necesita un valor inicial, ya que siempre debe devolver un valor en la suscripción, incluso si no ha recibido un next()
  • Tras la suscripción, devuelve el último valor del tema. Un observable regular solo se activa cuando recibe unonnext
  • en cualquier momento, puede recuperar el último valor del sujeto en un código no observable utilizando el getValue()método.

Las características únicas de un sujeto en comparación con un observable son:

  • Es un observador además de ser un observable por lo que también puedes enviar valores a un sujeto además de suscribirte a él.

Además, puede obtener un comportamiento observable del sujeto utilizando el asObservable()método en BehaviorSubject.

Observable es un genérico y BehaviorSubjecttécnicamente es un subtipo de observable porque BehaviorSubject es un observable con cualidades específicas.

Ejemplo con BehaviorSubject :

// Behavior Subject

// a is an initial value. if there is a subscription 
// after this, it would get "a" value immediately
let bSubject = new BehaviorSubject("a"); 

bSubject.next("b");

bSubject.subscribe(value => {
  console.log("Subscription got", value); // Subscription got b, 
                                          // ^ This would not happen 
                                          // for a generic observable 
                                          // or generic subject by default
});

bSubject.next("c"); // Subscription got c
bSubject.next("d"); // Subscription got d

Ejemplo 2 con tema regular:

// Regular Subject

let subject = new Subject(); 

subject.next("b");

subject.subscribe(value => {
  console.log("Subscription got", value); // Subscription wont get 
                                          // anything at this point
});

subject.next("c"); // Subscription got c
subject.next("d"); // Subscription got d

Se puede crear un observable a partir de ambos Subjecty BehaviorSubjectutilizando subject.asObservable().

La única diferencia es que no puede enviar valores a un next()método de uso observable .

En los servicios angulares, lo usaría BehaviorSubjectpara un servicio de datos ya que un servicio angular a menudo se inicializa antes de que el componente y el sujeto del comportamiento garanticen que el componente que consume el servicio reciba los últimos datos actualizados incluso si no hay nuevas actualizaciones desde la suscripción del componente a estos datos

210
Vamshi 2017-06-17 17:19.

Observable: resultado diferente para cada observador

Una diferencia muy importante. Dado que Observable es solo una función, no tiene ningún estado, por lo que para cada nuevo Observer, 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 Subject) almacena los detalles del observador, ejecuta el código solo una vez y da 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>

Salida:

"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ó una salida diferente para cada observador, pero BehaviorSubjectdio la misma salida para todos los observadores. Esto es importante.


Otras diferencias resumidas.

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃         Observable                  ┃     BehaviorSubject/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 Observable             ┃Can 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                          ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
71
Kedar9444 2018-11-18 11:47.

Observable y sujeta ambos son medios de observables un observador puede realizar un seguimiento de ellos. pero ambos tienen algunas características únicas. Además, hay un total de 3 tipos de temas, cada uno de ellos nuevamente tiene características únicas. intentemos comprender cada uno de ellos.

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

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 a observable (origen / maestro).

Subject

Están calientes: 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 a lo observable (origen / maestro).

Si está utilizando un sujeto, se pierde todos los valores que se transmiten antes de la creación del observador. Entonces aquí viene Replay Subject

ReplaySubject

Están calientes: 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 a lo observable (origen / maestro). más

Reproducir el flujo de mensajes: no importa cuándo se suscriba al tema de la reproducción, recibirá todos los mensajes transmitidos.

En sujeto y sujeto de repetición no se puede establecer el valor inicial como observable. Entonces aquí viene el sujeto conductual

BehaviorSubject

Están calientes: 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 a lo observable (origen / maestro). más

Reproducir el flujo de mensajes: no importa cuándo se suscriba al tema de la reproducción, recibirá todos los mensajes transmitidos.

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

29
Md Ayub Ali Sarker 2016-09-15 05:27.

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 del observador. El objeto Observable representa el objeto que envía notificaciones (el proveedor); el objeto Observer representa la clase que los recibe (el observador).

La clase Sujeto hereda tanto Observable como Observer, en el sentido de que es tanto un observador como un observable. Puede usar un tema para suscribir a todos los observadores y luego suscribir el tema a una fuente de datos de back-end.

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 en https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/subjects.md

20
Lukasz Marek Sielski 2017-09-06 04:59.

Una cosa que no veo en los ejemplos es que cuando lanza BehaviorSubject a Observable a través de asObservable, hereda el comportamiento de devolver el último valor en la suscripción.

Es la parte complicada, ya que a menudo las bibliotecas exponen campos como observables (es decir, params en ActivatedRoute en Angular2), pero pueden usar Subject o BehaviorSubject detrás de escena. Lo que usan afectaría el comportamiento de suscripción.

Ver aquí http://jsbin.com/ziquxapubo/edit?html,js,console

let A = new Rx.Subject();
let B = new Rx.BehaviorSubject(0);

A.next(1);
B.next(1);

A.asObservable().subscribe(n => console.log('A', n));
B.asObservable().subscribe(n => console.log('B', n));

A.next(2);
B.next(2);
12
Zameer Ansari 2018-01-24 20:44.

Un observable le permite suscribirse solo, mientras que un tema le permite publicar y suscribirse.

Por lo tanto, un tema permite que sus servicios se utilicen tanto como editor como como suscriptor.

A partir de ahora, no soy tan bueno, Observableasí que solo compartiré un ejemplo de Subject.

Entendamos mejor con un ejemplo de CLI angular . Ejecute los siguientes comandos:

npm install -g @angular/cli

ng new angular2-subject

cd angular2-subject

ng serve

Reemplace el contenido de app.component.htmlcon:

<div *ngIf="message">
  {{message}}
</div>

<app-home>
</app-home>

Ejecute el comando ng g c components/homepara generar el componente de inicio. Reemplace el contenido de home.component.htmlcon:

<input type="text" placeholder="Enter message" #message>
<button type="button" (click)="setMessage(message)" >Send message</button>

#messagees la variable local aquí. Agrega una propiedad message: string; a la app.component.tsclase de.

Ejecute este comando ng g s service/message. Esto generará un servicio en src\app\service\message.service.ts. Proporcione este servicio a la aplicación .

Importar Subjecta MessageService. Agrega un tema también. El código final se verá así:

import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';

@Injectable()
export class MessageService {

  public message = new Subject<string>();

  setMessage(value: string) {
    this.message.next(value); //it is publishing this value to all the subscribers that have already subscribed to this message
  }
}

Ahora, inyecte este servicio home.component.tsy pase una instancia del mismo al constructor. Haz esto app.component.tstambién. Utilice esta instancia de servicio para pasar el valor de #messagea la función de servicio setMessage:

import { Component } from '@angular/core';
import { MessageService } from '../../service/message.service';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})
export class HomeComponent {

  constructor(public messageService:MessageService) { }

  setMessage(event) {
    console.log(event.value);
    this.messageService.setMessage(event.value);
  }
}

En el interior app.component.ts, suscríbase y cancele la suscripción (para evitar pérdidas de memoria) a Subject:

import { Component, OnDestroy } from '@angular/core';
import { MessageService } from './service/message.service';
import { Subscription } from 'rxjs/Subscription';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html'
})
export class AppComponent {

  message: string;
  subscription: Subscription;

  constructor(public messageService: MessageService) { }

  ngOnInit() {
    this.subscription = this.messageService.message.subscribe(
      (message) => {
        this.message = message;
      }
    );
  }

  ngOnDestroy() {
    this.subscription.unsubscribe();
  }
}

Eso es.

Ahora, cualquier valor ingresado dentro #messagede home.component.htmlse imprimirá hacia {{message}}adentroapp.component.html

4
Chandru Dev 2018-12-12 03:03.

app.component.ts

behaviourService.setName("behaviour");

behaviour.service.ts

private name = new BehaviorSubject("");
getName = this.name.asObservable();`

constructor() {}

setName(data) {
    this.name.next(data);
}

custom.component.ts

behaviourService.subscribe(response=>{
    console.log(response);    //output: behaviour
});
1
Ronnel Reposo 2020-05-09 17:56.

Piense en Observables como una tubería con agua que fluye, a veces fluye agua y otras no. En algunos casos, es posible que necesite una tubería que siempre tenga agua, puede hacer esto creando una tubería especial que siempre contenga agua sin importar cuán pequeña sea, llamemos a esta tubería especial BehaviorSubject , si resulta que es proveedor de suministro de agua en su comunidad, puede dormir tranquilo por la noche sabiendo que su tubería recién instalada simplemente funciona.

En términos técnicos: puede encontrar casos de uso en los que un Observable siempre debe tener valor, tal vez desee capturar el valor de un texto de entrada a lo largo del tiempo, luego puede crear una instancia de BehaviorSubject para garantizar este tipo de comportamiento, digamos:


const firstNameChanges = new BehaviorSubject("<empty>");

// pass value changes.
firstNameChanges.next("Jon");
firstNameChanges.next("Arya");

A continuación, puede utilizar "valor" para muestrear cambios a lo largo del tiempo.


firstNameChanges.value;

Esto es útil cuando combina Observables más tarde, al observar el tipo de su transmisión como BehaviorSubject, puede asegurarse de que la transmisión al menos se dispare o emita una señal al menos una vez .

0
Flash 2019-04-04 00:52.

BehaviorSubject vs Observable : RxJS tiene observadores y observables, Rxjs ofrece múltiples clases para usar con flujos de datos, y una de ellas es BehaviorSubject.

Observables : Los observables son colecciones perezosas de múltiples valores a lo largo del tiempo.

BehaviorSubject : un sujeto que requiere un valor inicial y emite su valor actual a los nuevos suscriptores.

 // RxJS v6+
import { BehaviorSubject } from 'rxjs';

const subject = new BehaviorSubject(123);

//two new subscribers will get initial value => output: 123, 123
subject.subscribe(console.log);
subject.subscribe(console.log);

//two subscribers will get new value => output: 456, 456
subject.next(456);

//new subscriber will get latest value (456) => output: 456
subject.subscribe(console.log);

//all three subscribers will get new value => output: 789, 789, 789
subject.next(789);

// output: 123, 123, 456, 456, 456, 789, 789, 789
0
Yogesh Waghmare 2020-07-24 00:16.

Comportamiento Sujeto

BehaviorSubject se basa en la misma funcionalidad que nuestro ReplaySubject, como sujeto, caliente y reproduce el valor anterior.

BehaviorSubject agrega una pieza más de funcionalidad en la que puede darle un valor inicial a BehaviorSubject. Sigamos adelante y echemos un vistazo a ese código.

import { ReplaySubject } from 'rxjs';

const behaviorSubject = new BehaviorSubject(
  'hello initial value from BehaviorSubject'
);

behaviorSubject.subscribe(v => console.log(v));

behaviorSubject.next('hello again from BehaviorSubject');

Observables

Para comenzar, veremos la API mínima para crear un Observable regular. Hay un par de formas de crear un Observable. La forma en que crearemos nuestro Observable es instanciando la clase. Otros operadores pueden simplificar esto, pero querremos comparar el paso de instanciación con nuestros diferentes tipos observables.

import { Observable } from 'rxjs';

const observable = new Observable(observer => {
  setTimeout(() => observer.next('hello from Observable!'), 1000);
});

observable.subscribe(v => console.log(v));

Related questions

MORE COOL STUFF

La estrella de HGTV, Christina Hall, revela que tiene 'envenenamiento por mercurio y plomo' probablemente por voltear 'casas asquerosas'

La estrella de HGTV, Christina Hall, revela que tiene 'envenenamiento por mercurio y plomo' probablemente por voltear 'casas asquerosas'

La estrella de HGTV, Christina Hall, revela que le diagnosticaron envenenamiento por mercurio y plomo, probablemente debido a su trabajo como manipuladora de casas.

La estrella de 'Love Is Blind' Brennon Lemieux responde a los cargos de violencia doméstica

La estrella de 'Love Is Blind' Brennon Lemieux responde a los cargos de violencia doméstica

Recientemente salió a la luz un informe policial que acusa a la estrella de 'Love Is Blind', Brennon, de violencia doméstica. Ahora, Brennon ha respondido a los reclamos.

Wynonna Judd se dio cuenta de que ahora es la matriarca de la familia Judd en un momento festivo de pánico

Wynonna Judd se dio cuenta de que ahora es la matriarca de la familia Judd en un momento festivo de pánico

Conozca cómo Wynonna Judd se dio cuenta de que ahora es la matriarca de la familia mientras organizaba la primera celebración de Acción de Gracias desde que murió su madre, Naomi Judd.

Experto en lenguaje corporal explica los 'paralelos' entre Kate Middleton y la princesa Diana

Experto en lenguaje corporal explica los 'paralelos' entre Kate Middleton y la princesa Diana

Descubra por qué un destacado experto en lenguaje corporal cree que es fácil trazar "tales paralelismos" entre la princesa Kate Middleton y la princesa Diana.

Los láseres arrojan luz sobre por qué necesita cerrar la tapa antes de descargar

Los láseres arrojan luz sobre por qué necesita cerrar la tapa antes de descargar

Los inodoros arrojan columnas de aerosol invisibles con cada descarga. ¿Como sabemos? La prueba fue capturada por láseres de alta potencia.

The Secrets of Airline Travel Quiz

The Secrets of Airline Travel Quiz

Air travel is far more than getting from point A to point B safely. How much do you know about the million little details that go into flying on airplanes?

Where in the World Are You? Take our GeoGuesser Quiz

Where in the World Are You? Take our GeoGuesser Quiz

The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!

¿Caduca el repelente de insectos?

¿Caduca el repelente de insectos?

¿Sigue siendo efectivo ese lote de repelente de insectos que te quedó del verano pasado? Si es así, ¿por cuánto tiempo?

Ponle una tapa. En realidad, ponle una tapa a todo. Consigue 12 tapas de cocina elásticas de silicona por $14. [Exclusivo]

Ponle una tapa. En realidad, ponle una tapa a todo. Consigue 12 tapas de cocina elásticas de silicona por $14. [Exclusivo]

Tapas elásticas de silicona de Tomorrow's Kitchen, paquete de 12 | $14 | Amazonas | Código promocional 20OFFKINJALids son básicamente los calcetines de la cocina; siempre perdiéndose, dejando contenedores huérfanos que nunca podrán volver a cerrarse. Pero, ¿y si sus tapas pudieran estirarse y adaptarse a todos los recipientes, ollas, sartenes e incluso frutas en rodajas grandes que sobran? Nunca más tendrás que preocuparte por perder esa tapa tan específica.

Cuéntanos tus mejores trucos de Washington, DC

Cuéntanos tus mejores trucos de Washington, DC

Hemos pirateado algunas ciudades industriales en esta columna, como Los Ángeles y Las Vegas. Ahora es el momento de una ciudad militar-industrial-compleja.

Un minorista está eliminando su sección de tallas grandes y mezclando tallas más grandes con todo lo demás

Un minorista está eliminando su sección de tallas grandes y mezclando tallas más grandes con todo lo demás

Un minorista está enlatando su sección de tallas grandes. Pero no están tomando la categoría solo en línea o descontinuándola por completo.

La mejor forma de guardar animales de peluche es dentro de un puf

La mejor forma de guardar animales de peluche es dentro de un puf

Entiendo totalmente, completamente si tienes una relación difícil con los animales de peluche. Son lindos, tienen valor sentimental y es difícil separarse de ellos.

Patinaje artístico de EE. UU. 'frustrado' por falta de decisión final en evento por equipos, pide una decisión justa

Patinaje artístico de EE. UU. 'frustrado' por falta de decisión final en evento por equipos, pide una decisión justa

El equipo está a la espera de las medallas que ganó en los Juegos Olímpicos de Invierno de 2022 en Beijing, ya que se está resolviendo un caso de dopaje que involucra a la patinadora artística rusa Kamila Valieva.

Los compradores de Amazon dicen que duermen 'como un bebé mimado' gracias a estas fundas de almohada de seda que cuestan tan solo $ 10

Los compradores de Amazon dicen que duermen 'como un bebé mimado' gracias a estas fundas de almohada de seda que cuestan tan solo $ 10

Miles de compradores de Amazon recomiendan la funda de almohada de seda Mulberry, y está a la venta en este momento. La funda de almohada de seda viene en varios colores y ayuda a mantener el cabello suave y la piel clara. Compre las fundas de almohada de seda mientras tienen hasta un 46 por ciento de descuento en Amazon

Se busca al corredor de los Bengals Joe Mixon por orden de arresto emitida por presuntamente apuntar con un arma de fuego a una mujer

Se busca al corredor de los Bengals Joe Mixon por orden de arresto emitida por presuntamente apuntar con un arma de fuego a una mujer

El jueves se presentó una denuncia de delito menor amenazante agravado contra Joe Mixon.

Profesor de la Universidad de Purdue arrestado por presuntamente traficar metanfetamina y proponer favores sexuales a mujeres

Profesor de la Universidad de Purdue arrestado por presuntamente traficar metanfetamina y proponer favores sexuales a mujeres

El Departamento de Policía de Lafayette comenzó a investigar a un profesor de la Universidad de Purdue en diciembre después de recibir varias denuncias de un "hombre sospechoso que se acercaba a una mujer".

Concept Drift: el mundo está cambiando demasiado rápido para la IA

Concept Drift: el mundo está cambiando demasiado rápido para la IA

Al igual que el mundo que nos rodea, el lenguaje siempre está cambiando. Mientras que en eras anteriores los cambios en el idioma ocurrían durante años o incluso décadas, ahora pueden ocurrir en cuestión de días o incluso horas.

India me está pateando el culo

India me está pateando el culo

Estoy de vuelta por primera vez en seis años. No puedo decirte cuánto tiempo he estado esperando esto.

ℝ

“And a river went out of Eden to water the garden, and from thence it was parted and became into four heads” Genesis 2:10. ? The heart is located in the middle of the thoracic cavity, pointing eastward.

¿Merrick Garland le ha fallado a Estados Unidos?

Es más de la mitad de la presidencia de Biden. ¿Qué está esperando Merrick Garland?

¿Merrick Garland le ha fallado a Estados Unidos?

Creo, un poco tarde en la vida, en dar oportunidades a la gente. Generosamente.

Language