RxJS - Trabalhando com Assuntos

Um assunto é um observável que pode transmitir, ou seja, falar com muitos observadores. Considere um botão com um ouvinte de evento, a função anexada ao evento usando adicionar ouvinte é chamada toda vez que o usuário clica no botão, uma funcionalidade semelhante também vai para o assunto.

Vamos discutir os seguintes tópicos neste capítulo -

  • Crie um assunto
  • Qual é a diferença entre observável e sujeito?
  • Assunto Comportamento
  • Assunto Repetir
  • AsyncSubject

Crie um assunto

Para trabalhar com assunto, precisamos importar Assunto como mostrado abaixo -

import { Subject } from 'rxjs';

Você pode criar um objeto sujeito da seguinte maneira -

const subject_test = new Subject();

O objeto é um observador que possui três métodos -

  • next(v)
  • error(e)
  • complete()

Inscrever-se em um assunto

Você pode criar várias assinaturas sobre o assunto, conforme mostrado abaixo -

subject_test.subscribe({
   next: (v) => console.log(`From Subject : ${v}`)
});
subject_test.subscribe({
   next: (v) => console.log(`From Subject: ${v}`)
});

A assinatura é registrada no objeto subject, assim como addlistener que discutimos anteriormente.

Passando Dados para o Assunto

Você pode passar dados para o assunto criado usando o método next ().

subject_test.next("A");

Os dados serão repassados ​​a todas as assinaturas adicionadas no assunto.

Exemplo

Aqui está um exemplo prático do assunto -

import { Subject } from 'rxjs';

const subject_test = new Subject();

subject_test.subscribe({
   next: (v) => console.log(`From Subject : ${v}`)
});
subject_test.subscribe({
   next: (v) => console.log(`From Subject: ${v}`)
});
subject_test.next("A");
subject_test.next("B");

O objeto subject_test é criado chamando um novo Subject (). O objeto subject_test faz referência aos métodos next (), error () e complete (). O resultado do exemplo acima é mostrado abaixo -

Resultado

Podemos usar o método complete () para parar a execução do assunto conforme mostrado abaixo.

Exemplo

import { Subject } from 'rxjs';

const subject_test = new Subject();

subject_test.subscribe({
   next: (v) => console.log(`From Subject : ${v}`)
});
subject_test.subscribe({
   next: (v) => console.log(`From Subject: ${v}`)
});
subject_test.next("A");
subject_test.complete();
subject_test.next("B");

Depois de chamarmos complete, o próximo método chamado mais tarde não é invocado.

Resultado

Vamos agora ver como chamar o método error ().

Exemplo

Abaixo está um exemplo de trabalho -

import { Subject } from 'rxjs';

const subject_test = new Subject();

subject_test.subscribe({
   error: (e) => console.log(`From Subject : ${e}`)
});
subject_test.subscribe({
   error: (e) => console.log(`From Subject : ${e}`)
});
subject_test.error(new Error("There is an error"));

Resultado

Qual é a diferença entre observável e sujeito?

Um observável falará um a um, com o assinante. Sempre que você assinar o observável, a execução começará do zero. Faça uma chamada Http feita usando ajax e 2 assinantes chamando o observable. Você verá 2 solicitações HttpHttp na guia de rede do navegador.

Exemplo

Aqui está um exemplo prático do mesmo -

import { ajax } from 'rxjs/ajax';
import { map } from 'rxjs/operators';

let final_val = ajax('https://jsonplaceholder.typicode.com/users').pipe(map(e => e.response));
let subscriber1 = final_val.subscribe(a => console.log(a));
let subscriber2 = final_val.subscribe(a => console.log(a));

Resultado

Agora, aqui o problema é, queremos que os mesmos dados sejam compartilhados, mas não, ao custo de 2 chamadas Http. Queremos fazer uma chamada Http e compartilhar os dados entre os assinantes.

Isso será possível usando Assuntos. É um observável que pode transmitir, ou seja, conversar com muitos observadores. Ele pode compartilhar o valor entre os assinantes.

Exemplo

Aqui está um exemplo de trabalho usando assuntos -

import { Subject } from 'rxjs';
import { ajax } from 'rxjs/ajax';
import { map } from 'rxjs/operators';

const subject_test = new Subject();

subject_test.subscribe({
   next: (v) => console.log(v)
});
subject_test.subscribe({
   next: (v) => console.log(v)
});

let final_val = ajax('https://jsonplaceholder.typicode.com/users').pipe(map(e => e.response));
let subscriber = final_val.subscribe(subject_test);

Resultado

Agora você pode ver apenas uma chamada Http e os mesmos dados são compartilhados entre os assinantes chamados.

Assunto Comportamento

O assunto de comportamento fornecerá o valor mais recente quando chamado.

Você pode criar um assunto de comportamento conforme mostrado abaixo -

import { BehaviorSubject } from 'rxjs';
const subject = new BehaviorSubject("Testing Behaviour Subject"); 
// initialized the behaviour subject with value:Testing Behaviour Subject

Exemplo

Aqui está um exemplo prático para usar o Assunto Comportamento -

import { BehaviorSubject } from 'rxjs';
const behavior_subject = new BehaviorSubject("Testing Behaviour Subject"); 
// 0 is the initial value

behavior_subject.subscribe({
   next: (v) => console.log(`observerA: ${v}`)
});

behavior_subject.next("Hello");
behavior_subject.subscribe({
   next: (v) => console.log(`observerB: ${v}`)
});
behavior_subject.next("Last call to Behaviour Subject");

Resultado

Assunto Repetir

Um sujeito de replay é semelhante ao sujeito de comportamento, em que ele pode armazenar os valores e reproduzir os mesmos para os novos assinantes.

Exemplo

Aqui está um exemplo prático de assunto de repetição -

import { ReplaySubject } from 'rxjs';
const replay_subject = new ReplaySubject(2); 
// buffer 2 values but new subscribers

replay_subject.subscribe({
   next: (v) => console.log(`Testing Replay Subject A: ${v}`)
});

replay_subject.next(1);
replay_subject.next(2);
replay_subject.next(3);
replay_subject.subscribe({
   next: (v) => console.log(`Testing Replay Subject B: ${v}`)
});

replay_subject.next(5);

O valor do buffer usado é 2 no assunto de reprodução. Portanto, os dois últimos valores serão armazenados em buffer e usados ​​para os novos assinantes chamados.

Resultado

AsyncSubject

No caso de AsyncSubject, o último valor chamado é passado ao assinante e isso será feito somente após o método complete () ser chamado.

Exemplo

Aqui está um exemplo prático do mesmo -

import { AsyncSubject } from 'rxjs';

const async_subject = new AsyncSubject();

async_subject.subscribe({
   next: (v) => console.log(`Testing Async Subject A: ${v}`)
});

async_subject.next(1);
async_subject.next(2);
async_subject.complete();
async_subject.subscribe({
   next: (v) => console.log(`Testing Async Subject B: ${v}`)
});

Aqui, antes que complete é chamado, o último valor passado ao assunto é 2 e o mesmo que é dado aos assinantes.

Resultado