BehaviorSubject ist eine Art von Betreff, ein Betreff ist eine spezielle Art von Observable, sodass Sie Nachrichten wie jede andere Observable abonnieren können. Die einzigartigen Funktionen von BehaviorSubject sind:
- Es benötigt einen Anfangswert, da es im Abonnement immer einen Wert zurückgeben muss, auch wenn es keinen erhalten hat
next()
- Beim Abonnement wird der letzte Wert des Betreffs zurückgegeben. Ein reguläres Observable wird nur ausgelöst, wenn es ein empfängt
onnext
- Mit der
getValue()
Methode können Sie jederzeit den letzten Wert des Betreffs in einem nicht beobachtbaren Code abrufen .
Einzigartige Merkmale eines Subjekts im Vergleich zu einem beobachtbaren Objekt sind:
- Es ist nicht nur ein Beobachter, sondern auch ein Beobachter, sodass Sie neben dem Abonnieren auch Werte an ein Thema senden können.
Darüber hinaus können Sie mit der asObservable()
Methode on ein beobachtbares Verhaltensthema abrufen BehaviorSubject
.
Observable ist ein Generic und BehaviorSubject
technisch gesehen ein Untertyp von Observable, da BehaviorSubject ein Observable mit bestimmten Eigenschaften ist.
Beispiel mit 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
Beispiel 2 mit regulärem Thema:
// 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
Ein Observable kann aus beiden Subject
und BehaviorSubject
mit erstellt werden subject.asObservable()
.
Der einzige Unterschied besteht darin, dass Sie mit der next()
Methode keine Werte an ein Observable senden können .
In Angular-Diensten würde ich BehaviorSubject
für einen Datendienst verwenden, da ein Angular- Dienst häufig initialisiert wird, bevor Komponente und Verhaltenssubjekt sicherstellen, dass die Komponente, die den Dienst verbraucht, die zuletzt aktualisierten Daten erhält, auch wenn seit dem Abonnement dieser Daten durch die Komponente keine neuen Aktualisierungen vorliegen.
Beobachtbar: Unterschiedliches Ergebnis für jeden Beobachter
Ein sehr sehr wichtiger Unterschied. Da Observable nur eine Funktion ist, hat es keinen Status. Daher führt es für jeden neuen Observer den beobachtbaren Erstellungscode immer wieder aus. Das führt zu:
Dies führt zu schwerwiegenden Fehlern und Ineffizienzen
BehaviorSubject (oder Subject) speichert Beobachterdetails, führt den Code nur einmal aus und gibt das Ergebnis an alle Beobachter weiter.
Ex:
JSBin: http://jsbin.com/qowulet/edit?js,console
Ausgabe :
Beobachten Sie, wie die Verwendung
Observable.create
für jeden Beobachter unterschiedliche Ausgaben erzeugt hat, aberBehaviorSubject
für alle Beobachter die gleiche Ausgabe ergab. Das ist wichtig.Andere Unterschiede zusammengefasst.
quelle
KnockoutJS's ko.observable()
wird sofort mehr Parallelen zu sehenRx.BehaviorSubject
alsRx.Observable
Beobachtbar und Subjekt sind beide beobachtbar, dh ein Beobachter kann sie verfolgen. aber beide haben einige einzigartige Eigenschaften. Ferner gibt es insgesamt 3 Arten von Themen, von denen jedes wieder einzigartige Eigenschaften aufweist. Lassen Sie uns versuchen, jeden von ihnen zu verstehen.
Das praktische Beispiel finden Sie hier auf stackblitz . (Sie müssen die Konsole überprüfen, um die tatsächliche Ausgabe zu sehen.)
Observables
Sie sind kalt: Code wird ausgeführt, wenn sie mindestens einen einzigen Beobachter haben.
Erstellt eine Kopie der Daten: Observable erstellt eine Kopie der Daten für jeden Beobachter.
Unidirektional: Der Beobachter kann dem beobachtbaren Wert (Ursprung / Master) keinen Wert zuweisen.
Subject
Sie sind heiß: Code wird ausgeführt und der Wert wird gesendet, auch wenn kein Beobachter vorhanden ist.
Daten teilen : Dieselben Daten werden von allen Beobachtern geteilt.
bidirektional: Der Beobachter kann dem beobachtbaren Wert (Ursprung / Master) einen Wert zuweisen.
Wenn Sie den Betreff verwenden, verpassen Sie alle Werte, die vor der Erstellung des Beobachters gesendet werden. Hier kommt also das Thema "Wiedergabe"
ReplaySubject
Sie sind heiß: Code wird ausgeführt und der Wert wird gesendet, auch wenn kein Beobachter vorhanden ist.
Daten teilen : Dieselben Daten werden von allen Beobachtern geteilt.
bidirektional: Der Beobachter kann dem beobachtbaren Wert (Ursprung / Master) einen Wert zuweisen. Plus
Nachrichtenstrom erneut abspielen: Unabhängig davon, wann Sie den Betreff für die Wiedergabe abonnieren, erhalten Sie alle gesendeten Nachrichten.
In Betreff und Betreff wiedergeben können Sie den Anfangswert nicht auf beobachtbar setzen. Hier kommt also das Verhaltensthema
BehaviorSubject
Sie sind heiß: Code wird ausgeführt und der Wert wird gesendet, auch wenn kein Beobachter vorhanden ist.
Daten teilen : Dieselben Daten werden von allen Beobachtern geteilt.
bidirektional: Der Beobachter kann dem beobachtbaren Wert (Ursprung / Master) einen Wert zuweisen. Plus
Nachrichtenstrom erneut abspielen: Unabhängig davon, wann Sie den Betreff für die Wiedergabe abonnieren, erhalten Sie alle gesendeten Nachrichten.
Sie können den Anfangswert festlegen: Sie können das Observable mit dem Standardwert initialisieren.
quelle
ReplaySubject
eine Historie hat und eine Folge von (alten) Werten senden / senden kann. Nur wenn der Puffer auf 1 gesetzt ist, verhält er sich ähnlich wie aBehaviorSubject
.Das Observable-Objekt repräsentiert eine Push-basierte Sammlung.
Die Schnittstellen Observer und Observable bieten einen allgemeinen Mechanismus für die Push-basierte Benachrichtigung, der auch als Observer Design Pattern bezeichnet wird. Das Observable-Objekt stellt das Objekt dar, das Benachrichtigungen sendet (den Anbieter). Das Observer-Objekt repräsentiert die Klasse, die sie empfängt (den Observer).
Die Subject-Klasse erbt sowohl Observable als auch Observer in dem Sinne, dass sie sowohl Beobachter als auch Observable ist. Sie können einen Betreff verwenden, um alle Beobachter zu abonnieren, und dann den Betreff einer Backend-Datenquelle abonnieren
Weitere Informationen finden Sie unter https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/subjects.md
quelle
Eine Sache, die ich in Beispielen nicht sehe, ist, dass wenn Sie BehaviorSubject über asObservable in Observable umwandeln, das Verhalten der Rückgabe des letzten Werts beim Abonnement geerbt wird.
Es ist das Knifflige, da Bibliotheken Felder häufig als beobachtbar verfügbar machen (dh Parameter in ActivatedRoute in Angular2), aber möglicherweise Subject oder BehaviorSubject hinter den Kulissen verwenden. Was sie verwenden, würde das Abonnementverhalten beeinflussen.
Siehe hier http://jsbin.com/ziquxapubo/edit?html,js,console
quelle
Mit einem Observable können Sie nur abonnieren, während Sie mit einem Betreff sowohl veröffentlichen als auch abonnieren können.
Ein Betreff ermöglicht es also, Ihre Dienste sowohl als Herausgeber als auch als Abonnent zu verwenden.
Ab sofort bin ich nicht so gut darin,
Observable
daher werde ich nur ein Beispiel dafür nennenSubject
.Lassen Sie uns anhand eines Angular CLI- Beispiels besser verstehen . Führen Sie die folgenden Befehle aus:
Ersetzen Sie den Inhalt von
app.component.html
durch:Führen Sie den Befehl aus
ng g c components/home
, um die Home-Komponente zu generieren. Ersetzen Sie den Inhalt vonhome.component.html
durch:#message
ist hier die lokale Variable. Fügen Siemessage: string;
derapp.component.ts
Klasse von ' eine Eigenschaft hinzu .Führen Sie diesen Befehl aus
ng g s service/message
. Dadurch wird ein Dienst bei generiertsrc\app\service\message.service.ts
. Stellen Sie diesen Service für die App bereit .Importieren
Subject
inMessageService
. Fügen Sie auch ein Thema hinzu. Der endgültige Code soll folgendermaßen aussehen:Fügen Sie diesen Service nun ein
home.component.ts
und übergeben Sie eine Instanz davon an den Konstruktor. Tun Sie dies auch fürapp.component.ts
. Verwenden Sie diese Dienstinstanz, um den Wert von#message
an die Dienstfunktion zu übergebensetMessage
:Im Inneren
app.component.ts
können Sie Folgendes abonnieren und abbestellen (um Speicherverluste zu vermeiden)Subject
:Das ist es.
Nun trat jeder beliebige Wert innerhalb
#message
vonhome.component.html
wird zu bedruckenden{{message}}
innenapp.component.html
quelle
app.component.ts
behaviour.service.ts
custom.component.ts
quelle
BehaviorSubject vs Observable : RxJS verfügt über Beobachter und Observables, Rxjs bietet mehrere Klassen zur Verwendung mit Datenströmen an, und eine davon ist ein BehaviorSubject.
Observables : Observables sind verzögerte Sammlungen mehrerer Werte im Laufe der Zeit.
BehaviorSubject : Ein Betreff, der einen Anfangswert benötigt und seinen aktuellen Wert an neue Abonnenten ausgibt.
quelle
Stellen Sie sich Observables als ein Rohr mit fließendem Wasser vor, manchmal fließt Wasser und manchmal nicht. In einigen Fällen benötigen Sie möglicherweise tatsächlich ein Rohr, in dem sich immer Wasser befindet. Sie können dies tun, indem Sie ein spezielles Rohr erstellen, das immer ein Wasser enthält, egal wie klein es ist. Rufen Sie dieses spezielle Rohr BehaviorSubject auf , wenn Sie es gerade sind Als Wasserversorger in Ihrer Gemeinde können Sie nachts ruhig schlafen und wissen, dass Ihr neu installiertes Rohr einfach funktioniert.
In technischer Hinsicht: Es kann vorkommen, dass Anwendungsfälle auftreten, in denen ein Observable immer einen Wert enthalten sollte. Vielleicht möchten Sie den Wert eines Eingabetextes im Laufe der Zeit erfassen. Anschließend können Sie eine Instanz von BehaviorSubject erstellen, um diese Art von Verhalten sicherzustellen.
Sie können dann "Wert" verwenden, um Änderungen im Laufe der Zeit abzutasten.
Dies ist praktisch, wenn Sie Observables später kombinieren. Wenn Sie sich den Typ Ihres Streams als BehaviorSubject ansehen, können Sie sicherstellen, dass der Stream mindestens einmal ausgelöst oder signalisiert wird .
quelle