BehaviourSubject jest rodzajem tematu, temat jest specjalnym typem obserwowalnego, więc możesz subskrybować wiadomości jak każdy inny obserwowalny. Unikalne cechy BehaviorSubject to:
- Potrzebuje wartości początkowej, ponieważ zawsze musi zwrócić wartość przy subskrypcji, nawet jeśli nie otrzymała
next()
- Po subskrypcji zwraca ostatnią wartość przedmiotu. Regularne obserwowalne uruchamia się tylko wtedy, gdy otrzyma
onnext
- w dowolnym momencie możesz pobrać ostatnią wartość przedmiotu w nieobserwowalnym kodzie za pomocą tej
getValue()
metody.
Unikalne cechy przedmiotu w porównaniu do obserwowalnego to:
- Jest obserwatorem, a ponadto jest obserwowalny, dzięki czemu można także wysyłać wartości do przedmiotu oprócz subskrybowania go.
Ponadto można uzyskać obserwowalny obiekt z zachowaniem, stosując asObservable()
metodę na BehaviorSubject
.
Obserwowalny jest ogólny i BehaviorSubject
technicznie jest podtypem obserwowalnym, ponieważ obiekt behawioralny jest obserwowalny z określonymi cechami.
Przykład z 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
Przykład 2 z regularnym przedmiotem:
// 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
Obserwowalne można utworzyć zarówno z nich, jak Subject
i BehaviorSubject
przy użyciu subject.asObservable()
.
Jedyna różnica polega na tym, że nie można wysłać wartości do obserwowalnej za pomocą next()
metody.
W usługach Angular użyłbym usługi BehaviorSubject
danych, ponieważ usługa kątowa często inicjuje się, zanim komponent i zachowanie zapewni, że komponent korzystający z usługi odbierze ostatnie zaktualizowane dane, nawet jeśli nie będzie żadnych nowych aktualizacji od czasu subskrypcji komponentu na te dane.
Obserwowalny: inny wynik dla każdego obserwatora
Jedna bardzo ważna różnica. Ponieważ Observable jest tylko funkcją, nie ma żadnego stanu, więc dla każdego nowego Observera wykonuje powtarzalny kod tworzenia. To skutkuje:
To powoduje poważne błędy i nieefektywności
BehaviorSubject (lub Subject) przechowuje dane obserwatora, uruchamia kod tylko raz i daje wynik wszystkim obserwatorom.
Dawny:
JSBin: http://jsbin.com/qowulet/edit?js,console
Wynik :
Obserwuj, jak przy użyciu
Observable.create
utworzono różne dane wyjściowe dla każdego obserwatora, aleBehaviorSubject
dało to samo wyjście dla wszystkich obserwatorów. To jest ważne.Inne różnice podsumowane.
źródło
KnockoutJS's ko.observable()
, natychmiast zobaczy więcej podobieństwRx.BehaviorSubject
doRx.Observable
Obserwowalne i podmiotowe są obserwowalne, co oznacza, że obserwator może je śledzić. ale oba mają pewne unikalne cechy. Ponadto istnieją w sumie 3 rodzaje przedmiotów, z których każdy ponownie ma unikalne cechy. spróbujmy zrozumieć każdy z nich.
praktyczny przykład znajdziesz tutaj na stackblitz . (Musisz sprawdzić konsolę, aby zobaczyć rzeczywiste wyjście)
Observables
Są zimni: kod jest wykonywany, gdy ma przynajmniej jednego obserwatora.
Tworzy kopię danych: Observable tworzy kopię danych dla każdego obserwatora.
Jednokierunkowy: Obserwator nie może przypisać wartości do obserwowalnej (origin / master).
Subject
Są gorące: kod jest wykonywany, a wartość jest rozgłaszana, nawet jeśli nie ma obserwatora.
Udostępnia dane: Te same dane są udostępniane wszystkim obserwatorom.
dwukierunkowy: Obserwator może przypisać wartość do obserwowalnej (origin / master).
Jeśli używasz tematu, tracisz wszystkie wartości, które są nadawane przed utworzeniem obserwatora. A więc nadchodzi powtórka
ReplaySubject
Są gorące: kod jest wykonywany, a wartość przekazywana, nawet jeśli nie ma obserwatora.
Udostępnia dane: Te same dane są udostępniane wszystkim obserwatorom.
dwukierunkowy: Obserwator może przypisać wartość do obserwowalnej (origin / master). plus
Odtwórz strumień wiadomości: bez względu na to, czy subskrybujesz temat powtórki, otrzymasz wszystkie nadawane wiadomości.
W temacie i powtórzeniu nie można ustawić wartości początkowej na możliwą do zaobserwowania. A więc nadchodzi Obiekt Behawioralny
BehaviorSubject
Są gorące: kod jest wykonywany, a wartość przekazywana, nawet jeśli nie ma obserwatora.
Udostępnia dane: Te same dane są udostępniane wszystkim obserwatorom.
dwukierunkowy: Obserwator może przypisać wartość do obserwowalnej (origin / master). plus
Odtwórz strumień wiadomości: bez względu na to, czy subskrybujesz temat powtórki, otrzymasz wszystkie nadawane wiadomości.
Możesz ustawić wartość początkową: Możesz zainicjalizować obserwowalną wartość domyślną.
źródło
ReplaySubject
ma historię i może nadawać / emitować sekwencję (starych) wartości. Tylko gdy bufor jest ustawiony na 1, zachowuje się podobnie jak aBehaviorSubject
.Obserwowalny obiekt reprezentuje kolekcję opartą na wypychaniu.
Interfejsy obserwatora i obserwowalnego zapewniają uogólniony mechanizm powiadomień opartych na wypychaniu, znany również jako wzorzec projektu obserwatora. Obserwowalny obiekt reprezentuje obiekt, który wysyła powiadomienia (dostawca); obiekt Observer reprezentuje klasę, która je odbiera (obserwator).
Klasa Subject dziedziczy zarówno Obserwowalny, jak i Obserwator, w tym sensie, że jest zarówno obserwatorem, jak i obserwowalnym. Możesz użyć podmiotu, aby zasubskrybować wszystkich obserwatorów, a następnie zasubskrybować ten temat do źródła danych zaplecza
Więcej na https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/subjects.md
źródło
Jednej rzeczy, której nie widzę w przykładach, jest to, że kiedy rzutujesz BehaviorSubject na Observable za pośrednictwem asObservable, dziedziczy zachowanie zwracania ostatniej wartości po subskrypcji.
Jest to trudny bit, ponieważ biblioteki często ujawniają pola jako obserwowalne (tj. Parametry w ActivatedRoute w Angular2), ale mogą używać obiektu Subject lub BehaviorSubject za scenami. Ich użycie wpłynęłoby na zachowanie subskrybowania.
Zobacz tutaj http://jsbin.com/ziquxapubo/edit?html,js,console
źródło
Obserwowalne pozwala subskrybować tylko natomiast tematu pozwala zarówno publikowania i subskrybowania.
Zatem przedmiot zezwala na twoje usługi zarówno jako wydawca, jak i subskrybent.
W tej chwili nie jestem zbyt dobry,
Observable
więc podzielę się tylko przykłademSubject
.Lepiej zrozummy na przykładzie Angular CLI . Uruchom poniższe polecenia:
Zamień zawartość na
app.component.html
:Uruchom polecenie,
ng g c components/home
aby wygenerować komponent główny. Zamień zawartość nahome.component.html
:#message
jest tutaj zmienną lokalną. Dodaj właściwośćmessage: string;
doapp.component.ts
klasy.Uruchom to polecenie
ng g s service/message
. Spowoduje to wygenerowanie usługi nasrc\app\service\message.service.ts
. Zapewnij tę usługę aplikacji .Importuj
Subject
doMessageService
. Dodaj też temat. Ostateczny kod powinien wyglądać następująco:Teraz wstaw tę usługę
home.component.ts
i przekaż jej instancję do konstruktora. Zrób toapp.component.ts
też. Użyj tej instancji usługi do przekazania wartości#message
do funkcji usługisetMessage
:Wewnątrz
app.component.ts
subskrybuj i anuluj subskrypcję (aby zapobiec wyciekom pamięci) doSubject
:Otóż to.
Teraz każda wartość weszła do środka
#message
zhome.component.html
drukowane są do{{message}}
wewnątrzapp.component.html
źródło
app.component.ts
behiour.service.ts
custom.component.ts
źródło
BehaviorSubject vs Observable : RxJS ma obserwatorów i obserwowalnych, Rxjs oferuje wiele klas do wykorzystania ze strumieniami danych, a jedną z nich jest BehaviorSubject.
Obserwowalne : Obserwowalne to leniwe zbiory wielu wartości w czasie.
BehaviorSubject : Temat, który wymaga wartości początkowej i wysyła swoją aktualną wartość do nowych subskrybentów.
źródło
Pomyśl o Obserwowalnych jako o rurze z przepływającą wodą, czasem woda płynie, a czasem nie. W niektórych przypadkach może być potrzebna rura, która zawsze ma w sobie wodę, możesz to zrobić, tworząc specjalną rurę, która zawsze zawiera wodę, bez względu na to, jak mała jest, nazwijmy tę specjalną rurę BehaviorSubject , jeśli tak się dzieje jako dostawca wody w Twojej społeczności, możesz spać spokojnie w nocy, wiedząc, że nowo zainstalowana rura po prostu działa.
Z technicznego punktu widzenia: możesz napotkać przypadki użycia, w których obserwowalny powinien zawsze mieć wartość, być może chcesz przechwycić wartość tekstu wejściowego w czasie, możesz następnie utworzyć instancję BehaviorSubject, aby zapewnić takie zachowanie, powiedzmy:
Następnie można użyć „wartości” do próbkowania zmian w czasie.
Jest to przydatne, gdy później połączysz obserwowalne, sprawdzając typ strumienia jako BehaviorSubject, możesz następnie upewnić się, że strumień przynajmniej odpala lub sygnalizuje przynajmniej raz .
źródło