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.