Ich habe versucht, diese 3 zu verstehen:
Betreff , Verhaltensthema und Wiederholungsfach . Ich möchte sie verwenden und wissen, wann und warum, welche Vorteile sie haben, und obwohl ich die Dokumentation gelesen, Tutorials angesehen und Google durchsucht habe, habe ich keinen Sinn daraus gemacht.
Was ist ihr Zweck? Ein realer Fall wäre sehr dankbar, wenn er nicht einmal codieren müsste.
Ich würde eine saubere Erklärung vorziehen, nicht nur "a + b => c, das Sie abonniert haben ..."
Danke dir
javascript
angular
rxjs
reactive-programming
angular2-observables
Paul Samsotha
quelle
quelle
Antworten:
Es kommt wirklich auf Verhalten und Semantik an. Mit einer
Subject
- Ein Abonnent erhält nur veröffentlichte Werte, die nach dem Abonnement ausgegeben wurden. Fragen Sie sich, ist es das, was Sie wollen? Muss der Abonnent etwas über vorherige Werte wissen? Wenn nicht, können Sie dies verwenden, andernfalls wählen Sie eine der anderen. Zum Beispiel bei der Kommunikation von Komponente zu Komponente. Angenommen, Sie haben eine Komponente, die Ereignisse für andere Komponenten auf Knopfdruck veröffentlicht. Sie können einen Dienst mit einem Betreff zur Kommunikation verwenden.BehaviorSubject
- Der letzte Wert wird zwischengespeichert. Ein Abonnent erhält beim ersten Abonnement den neuesten Wert. Die Semantik für dieses Thema besteht darin, einen Wert darzustellen, der sich im Laufe der Zeit ändert. Zum Beispiel ein angemeldeter Benutzer. Der ursprüngliche Benutzer kann ein anonymer Benutzer sein. Sobald sich ein Benutzer anmeldet, ist der neue Wert der authentifizierte Benutzerstatus.Das
BehaviorSubject
wird mit einem Anfangswert initialisiert. Dies ist manchmal wichtig für die Codierungspräferenz. Angenommen, Sie initialisieren es mit anull
. Dann müssen Sie in Ihrem Abonnement eine Nullprüfung durchführen. Vielleicht OK oder vielleicht nervig.ReplaySubject
- Es kann bis zu einer bestimmten Anzahl von Emissionen zwischengespeichert werden. Alle Abonnenten erhalten beim Abonnement alle zwischengespeicherten Werte. Wann würden Sie dieses Verhalten brauchen? Ehrlich gesagt hatte ich keine Notwendigkeit für ein solches Verhalten, außer im folgenden Fall:Wenn Sie a
ReplaySubject
mit einer Puffergröße von initialisieren1
, verhält es sich tatsächlich wie aBehaviorSubject
. Der letzte Wert wird immer zwischengespeichert, sodass er sich wie ein Wert verhält, der sich im Laufe der Zeit ändert. Damit ist keinenull
Prüfung erforderlich, wie im Fall derBehaviorSubject
mit a initialisiertennull
. In diesem Fall wird bis zur ersten Veröffentlichung kein Wert an den Abonnenten ausgegeben.Es kommt also wirklich auf das Verhalten an, das Sie erwarten (für welches Sie es verwenden möchten). Die meiste Zeit werden Sie wahrscheinlich eine verwenden wollen,
BehaviorSubject
weil das, was Sie wirklich darstellen möchten, die Semantik "Wert über Zeit" ist. Aber ich persönlich sehe nichts falsches an der Ersetzung vonReplaySubject
initialisiert durch1
.Was Sie vermeiden möchten, ist die Verwendung der Vanille,
Subject
wenn Sie wirklich ein Caching-Verhalten benötigen. Nehmen wir zum Beispiel, Sie schreiben einen Routing Guard oder eine Lösung. Sie rufen einige Daten in diesem Guard ab und legen sie in einem Dienst festSubject
. Dann abonnieren Sie in der gerouteten Komponente den betreffenden Dienst, um zu versuchen, den Wert zu erhalten, der im Guard ausgegeben wurde. Hoppla. Wo ist der Wert? Es wurde bereits ausgestrahlt, DUH. Verwenden Sie ein "Caching" -Thema!Siehe auch:
quelle
ReplaySubject
mit einer Puffergröße von 1 war genau das, was ich brauchte. Ich hatte einen Streckenwächter, der den Wert brauchte, aber auf die erste Emission warten musste. ABehaviorSubject
schnitt es also nicht ab, da ich keinen Anfangswert wollte (null
würde auch nicht funktionieren, weil ich ihn zur Kennzeichnung eines Zustands verwendete)resolve
Guard-Klasse. Mein Datendienst kann asynchron oder synchron sein (wenn die Daten bereits abgerufen wurden). Wenn es synchron war, wurde Subject.next () ausgelöst, bevor dieresolve
Funktion zurückgegeben und von Angular intern abonniert wurde. BehaviourSubject würde möglicherweise funktionieren, aber ich müsste explizit aufrufencomplete()
und auchnull
Überprüfungen für den Anfangswert hinzufügen . Was funktionierte war neuReplaySubject<DataType>(1)
undresolveSubject.asObservable().take(1).map(....)
.asObservable()
sende ich, wenn ich ein Observable mit dem Observable erhalte , einen Wert vonnull
an Abonnenten, bevor ichnext()
mein ReplaySubject aufrufe. Ich dachte, es sollte im Gegensatz zu BehaviorSubject keinen Anfangswert haben?Eine handliche Zusammenfassung der verschiedenen beobachtbaren Typen, nicht intuitive Benennung, die ich kenne lol .
Subject
- Ein Abonnent erhält erst nach Abschluss des Abonnements veröffentlichte Werte.BehaviorSubject
- Neue Abonnenten erhalten unmittelbar nach dem Abonnement den zuletzt veröffentlichten Wert ODER den Anfangswert.ReplaySubject
- Neue Abonnenten erhalten alle zuvor veröffentlichten Werte sofort nach dem Abonnementquelle
In diesem Beispiel ist hier das Ergebnis, das in der Konsole gedruckt wird:
Hier ist ein Verwendungsbeispiel für Wiedergabethemen, bei denen a
buffer of 2 previous values
für neue Abonnements beibehalten und ausgegeben wird:Folgendes gibt uns das an der Konsole:
Und das Ergebnis:
Referenz: https://alligator.io/rxjs/subjects/
quelle
Aus: Randall Koutnik Buch „Erstellen Sie reaktive Websites mit RxJS.“ ::
Ein Subjekt ist ein Objekt, das mit Turbolader beobachtet werden kann. Im Kern verhält sich ein Betreff ähnlich wie ein reguläres Observable, aber jedes Abonnement ist an dieselbe Quelle gebunden. Die Probanden sind auch Beobachter und verfügen über Next-, Error- und Doed-Methoden, um Daten gleichzeitig an alle Abonnenten zu senden. Da Subjekte Beobachter sind, können sie direkt an einen Abonnementanruf weitergeleitet werden, und alle Ereignisse aus dem ursprünglichen Observable werden über das Subjekt an seine Abonnenten gesendet.
Wir können das ReplaySubject verwenden, um den Verlauf zu verfolgen. Ein ReplaySubject zeichnet die letzten n Ereignisse auf und sendet sie an jeden neuen Abonnenten zurück. Zum Beispiel in der Chat-Anwendung. Wir können es verwenden, um die Aufzeichnung des vorherigen Chat-Verlaufs zu verfolgen.
Ein BehaviorSubject ist eine vereinfachte Version des ReplaySubject . Das ReplaySubject hat eine beliebige Anzahl von Ereignissen gespeichert, das BehaviorSubject zeichnet nur den Wert des letzten Ereignisses auf. Wenn ein BehaviorSubject ein neues Abonnement aufzeichnet, gibt es den neuesten Wert an den Abonnenten sowie alle neu übergebenen Werte aus. Das BehaviorSubject ist nützlich, wenn es sich um einzelne Statuseinheiten handelt, z. B. Konfigurationsoptionen.
quelle
Die am meisten befürwortete Antwort ist eindeutig falsch und behauptet:
"Wenn Sie a
ReplaySubject
mit einer Puffergröße von 1 initialisieren , verhält es sich tatsächlich wie a.BehaviorSubject
"Das ist nicht ganz richtig; In diesem großartigen Blog-Beitrag erfahren Sie, welche Unterschiede zwischen diesen beiden bestehen. Wenn Sie beispielsweise einen abgeschlossenen abonnieren
BehaviorSubject
, erhalten Sie nicht den letzten Wert, sondern einenReplaySubject(1)
.Dies ist ein wichtiger Unterschied, der nicht übersehen werden sollte:
Überprüfen Sie dieses Codebeispiel hier, das aus einem anderen großartigen Blog-Beitrag zum Thema stammt.
quelle
quelle