RxJS - Praca z podmiotami

Podmiot jest obserwowalnym obiektem, który może być rozsyłany grupowo, tj. Rozmawiać z wieloma obserwatorami. Rozważmy przycisk z detektorem zdarzenia, funkcja dołączona do zdarzenia przy użyciu funkcji add listener jest wywoływana za każdym razem, gdy użytkownik kliknie przycisk. Podobna funkcjonalność dotyczy również tematu.

W tym rozdziale omówimy następujące tematy -

  • Utwórz temat
  • Jaka jest różnica między obserwowalnymi a podmiotowymi?
  • Temat zachowania
  • Powtórz temat
  • AsyncSubject

Utwórz temat

Aby pracować z tematem, musimy zaimportować temat, jak pokazano poniżej -

import { Subject } from 'rxjs';

Możesz utworzyć obiekt podmiotu w następujący sposób -

const subject_test = new Subject();

Obiekt jest obserwatorem, który ma trzy metody -

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

Zasubskrybuj temat

Możesz utworzyć wiele subskrypcji na ten temat, jak pokazano poniżej -

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

Subskrypcja jest rejestrowana w obiekcie podmiotu, tak jak omawialiśmy wcześniej addlistener.

Przekazywanie danych podmiotowi

Możesz przekazać dane podmiotowi utworzonemu za pomocą metody next ().

subject_test.next("A");

Dane zostaną przekazane wszystkim abonamentom dodanym na ten temat.

Przykład

Oto roboczy przykład tematu -

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

Obiekt subject_test jest tworzony przez wywołanie nowej metody Subject (). Obiekt subject_test odwołuje się do metod next (), error () i complete (). Dane wyjściowe powyższego przykładu pokazano poniżej -

Wynik

Możemy użyć metody complete (), aby zatrzymać wykonywanie podmiotu, jak pokazano poniżej.

Przykład

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

Po wywołaniu complete następna metoda wywoływana później nie jest wywoływana.

Wynik

Zobaczmy teraz, jak wywołać metodę error ().

Przykład

Poniżej znajduje się działający przykład -

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

Wynik

Jaka jest różnica między obserwowalnymi a podmiotowymi?

Obserwowalny porozmawia jeden z drugim, z abonentem. Za każdym razem, gdy subskrybujesz obserwowalne, wykonanie rozpocznie się od zera. Weź wywołanie HTTP wykonane przy użyciu ajax i 2 subskrybentów wywołujących obserwowalne. Na karcie sieci przeglądarki zobaczysz 2 żądania HttpHttp.

Przykład

Oto działający przykład tego samego -

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

Wynik

Teraz problem polega na tym, że chcemy, aby te same dane były udostępniane, ale nie kosztem 2 wywołań HTTP. Chcemy wykonać jedno połączenie HTTP i udostępnić dane abonentom.

Będzie to możliwe za pomocą przedmiotów. Jest to obserwowalne, które mogą być rozsyłane grupowo, tj. Rozmawiać z wieloma obserwatorami. Może dzielić wartość między subskrybentów.

Przykład

Oto działający przykład z użyciem przedmiotów -

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

Wynik

Teraz możesz zobaczyć tylko jedno połączenie HTTP i te same dane są udostępniane między wywoływanymi abonentami.

Temat zachowania

Temat zachowania poda ci ostatnią wartość po wywołaniu.

Możesz stworzyć temat zachowania, jak pokazano poniżej -

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

Przykład

Oto działający przykład użycia tematu zachowania -

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

Wynik

Powtórz temat

Obiekt powtórki jest podobny do tematu zachowania, w którym może buforować wartości i odtwarzać to samo nowym subskrybentom.

Przykład

Oto działający przykład tematu powtórki -

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

Użyta wartość bufora to 2 w temacie powtórki. Więc ostatnie dwie wartości zostaną zbuforowane i użyte dla nowych wywoływanych abonentów.

Wynik

AsyncSubject

W przypadku AsyncSubject ostatnia wywołana wartość jest przekazywana do subskrybenta i zostanie to zrobione dopiero po wywołaniu metody complete ().

Przykład

Oto działający przykład tego samego -

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

Tutaj, przed wywołaniem complete, ostatnią wartością przekazaną podmiotowi jest 2 i taką samą, jaką otrzymali subskrybenci.

Wynik