RxJS - Работа с предметами

Субъект - это наблюдаемое, которое может передавать многоадресную рассылку, то есть разговаривать со многими наблюдателями. Рассмотрим кнопку с прослушивателем событий, функция, прикрепленная к событию с помощью добавления прослушивателя, вызывается каждый раз, когда пользователь нажимает кнопку, аналогичная функция распространяется и на тему.

В этой главе мы собираемся обсудить следующие темы -

  • Создать тему
  • В чем разница между наблюдаемым и субъектом?
  • Тема поведения
  • Повторить тему
  • AsyncSubject

Создать тему

Чтобы работать с темой, нам нужно импортировать тему, как показано ниже -

import { Subject } from 'rxjs';

Вы можете создать субъектный объект следующим образом -

const subject_test = new Subject();

Объект - это наблюдатель, у которого есть три метода:

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

Подпишитесь на тему

Вы можете создать несколько подписок по теме, как показано ниже -

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

Подписка регистрируется на субъектный объект так же, как addlistener, о котором мы говорили ранее.

Передача данных субъекту

Вы можете передать данные субъекту, созданному с помощью метода next ().

subject_test.next("A");

Данные будут переданы во все подписки, добавленные по теме.

пример

Вот рабочий пример предмета -

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");

Объект subject_test создается путем вызова нового Subject (). Объект subject_test имеет ссылку на методы next (), error () и complete (). Результат приведенного выше примера показан ниже -

Вывод

Мы можем использовать метод complete (), чтобы остановить выполнение объекта, как показано ниже.

пример

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");

Как только мы вызываем complete, следующий метод, вызываемый позже, не вызывается.

Вывод

Давайте теперь посмотрим, как вызвать метод error ().

пример

Ниже рабочий пример -

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"));

Вывод

В чем разница между наблюдаемым и субъектом?

Наблюдаемый будет разговаривать с абонентом один на один. Каждый раз, когда вы подписываетесь на наблюдаемое, выполнение начнется с нуля. Возьмите Http-вызов, сделанный с использованием ajax, и 2 подписчика, вызывающих наблюдаемый. Вы увидите 2 запроса HttpHttp на вкладке сети браузера.

пример

Вот рабочий пример того же -

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));

Вывод

Проблема в том, что мы хотим, чтобы одни и те же данные использовались совместно, но не за счет двух вызовов Http. Мы хотим сделать один Http-вызов и поделиться данными между подписчиками.

Это будет возможно с помощью Subjects. Это наблюдаемое, которое может выполнять многоадресную передачу, то есть разговаривать со многими наблюдателями. Он может разделить ценность между подписчиками.

пример

Вот рабочий пример с использованием предметов -

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);

Вывод

Теперь вы можете видеть только один вызов Http, и одни и те же данные распределяются между вызываемыми абонентами.

Тема поведения

При вызове субъект поведения сообщит вам последнее значение.

Вы можете создать тему поведения, как показано ниже -

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

пример

Вот рабочий пример использования темы поведения -

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");

Вывод

Повторить тему

Субъект повторного воспроизведения аналогичен субъекту поведения, при этом он может буферизовать значения и воспроизводить их для новых подписчиков.

пример

Вот рабочий пример темы воспроизведения -

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);

Используемое значение буфера - 2 для темы воспроизведения. Таким образом, последние два значения будут помещены в буфер и будут использоваться для вызываемых новых подписчиков.

Вывод

AsyncSubject

В случае AsyncSubject последнее вызванное значение передается подписчику, и это будет сделано только после вызова метода complete ().

пример

Вот рабочий пример того же -

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}`)
});

Здесь перед вызовом complete последнее значение, переданное субъекту, равно 2, и то же самое, что и подписчикам.

Вывод