Subjekt vs. VerhaltenSubject vs. ReplaySubject in Angular

Lesezeit: 10 Minuten

Ich habe versucht, diese 3 zu verstehen:

Ich würde sie gerne verwenden und wissen, wann und warum, was die Vorteile ihrer Verwendung sind, und obwohl ich die Dokumentation gelesen, Tutorials angesehen und Google durchsucht habe, habe ich keinen Sinn darin verstanden.

Was sind also ihre Zwecke? Ein Fall aus der realen Welt wäre am meisten zu schätzen, da er nicht einmal codiert werden muss.

Ich würde eine saubere Erklärung bevorzugen, nicht nur “a + b => c, Sie haben … abonniert.”

Danke schön

  • Es gibt bereits eine Frage mit Verhaltenssubjekt mit Beobachtbarem; stackoverflow.com/questions/39494058/… und die Dokumentation zum Thema Wiedergabe ist imo klar github.com/Reactive-Extensions/RxJS/blob/master/doc/api/…

    – Öko

    30. März 17 um 13:12 Uhr

  • In dieser Antwort finden Sie eine relativ gründliche Darstellung der Themen in Rxjs, die die Antwort von Peeksilet gut ergänzt. Dazu gehören auch wichtige Details zum Verhalten nach der Kündigung, also lohnt es sich, einen Blick darauf zu werfen.

    – Benutzer3743222

    30. März 17 um 22:12 Uhr


Subjekt vs VerhaltenSubject vs ReplaySubject in Angular
Paul Samsotha

Es kommt wirklich auf Verhalten und Semantik an. Mit einer

  • Subject – Ein Abonnent erhält nur veröffentlichte Werte, die ausgegeben wurden nach das Abonnement. Fragen Sie sich, ist es das, was Sie wollen? Muss der Abonnent etwas über frühere Werte wissen? Wenn nicht, dann können Sie diese verwenden, ansonsten wählen Sie eine der anderen. Beispielsweise bei der Kommunikation von Komponente zu Komponente. Angenommen, Sie haben eine Komponente, die auf Knopfdruck Ereignisse für andere Komponenten veröffentlicht. Sie können einen Dienst mit einem Betreff verwenden, um zu kommunizieren.

  • BehaviorSubject – Der letzte Wert wird zwischengespeichert. Ein Abonnent erhält den neuesten Wert beim Erstabonnement. Die Semantik für dieses Subjekt soll einen Wert darstellen, der sich im Laufe der Zeit ändert. Zum Beispiel ein eingeloggter Benutzer. Der anfängliche Benutzer kann ein anonymer Benutzer sein. Aber sobald sich ein Benutzer anmeldet, ist der neue Wert der authentifizierte Benutzerstatus.

    Der BehaviorSubject wird mit einem Anfangswert initialisiert. Dies ist manchmal wichtig für die Codierungspräferenz. Angenommen, Sie initialisieren es mit a null. 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 zwischenspeichern. Alle Abonnenten erhalten alle zwischengespeicherten Werte beim Abonnement. Wann würden Sie dieses Verhalten brauchen? Ehrlich gesagt hatte ich keinen Bedarf für ein solches Verhalten, außer in folgendem Fall:

    Wenn Sie eine initialisieren ReplaySubject mit einer Puffergröße von 1, dann ist es tatsächlich verhält genau wie ein BehaviorSubject. Der letzte Wert wird immer zwischengespeichert, verhält sich also wie ein Wert, der sich im Laufe der Zeit ändert. Damit erübrigt sich ein null überprüfen Sie wie im Fall der BehaviorSubject mit a initialisiert null. In diesem Fall wird bis zur ersten Veröffentlichung niemals ein Wert an den Abonnenten ausgegeben.

Es kommt also wirklich auf das Verhalten an, das Sie erwarten (was Sie verwenden sollen). Meistens werden Sie wahrscheinlich a verwenden wollen BehaviorSubject denn was Sie wirklich darstellen möchten, ist die Semantik “Wert im Laufe der Zeit”. Aber ich persönlich sehe nichts falsch mit der Substitution von ReplaySubject initialisiert mit 1.

Was du willst vermeiden verwendet die Vanille Subject wenn Sie wirklich etwas Caching-Verhalten brauchen. Nehmen Sie zum Beispiel an, Sie schreiben einen Routing-Wächter oder eine Lösung. Sie rufen einige Daten in diesem Wächter ab und legen sie in einem Dienst fest Subject. Dann abonnieren Sie in der gerouteten Komponente das Dienstsubjekt, um zu versuchen, den Wert zu erhalten, der im Wächter ausgegeben wurde. Hoppla. Wo ist der Wert? Es wurde bereits emittiert, DUH. Verwenden Sie ein “Caching”-Thema!

Siehe auch:

  • Was sind RxJS-Subjekte und die Vorteile ihrer Verwendung?

  • Dies ist kurz und einfach, um die Unterschiede zu verstehen. Wenn sich der Wert im Dienst ändert und sich auch die Komponenten ändern, dass der Wert angezeigt wird, dann ist BehaviourSubjects oder Replay Subject die Lösung.

    – Saiyaff Farouk

    19. Mai ’17 um 14:51 Uhr

  • Danke schön! ReplaySubject mit einer Puffergröße von 1 war genau das, was ich brauchte. Ich hatte einen Routenwächter, der den Wert brauchte, aber auf die erste Emission warten musste. Also ein BehaviorSubject habe es nicht geschnitten, da ich keinen Anfangswert haben wollte (null würde auch nicht funktionieren, weil ich es benutzt habe, um einen Zustand zu bezeichnen)

    – Andreas M.

    8. Januar 18 um 4:09 Uhr

  • ReplaySubject mit einem Puffer von 1 unterscheidet sich von BehaviorSubject darin, dass ReplaySubject den Abonnenten blockiert, der auf den ersten Wert wartet, während BehaviorSubject einen Anfangswert erfordert, wenn es erstellt wird. Oft möchten Sie Daten faul bei Bedarf abrufen und haben keinen Anfangswert.

    – Pat Niemeyer

    4. August 18 um 23:20 Uhr


  • “Wenn Sie eine initialisieren ReplaySubject mit einer Puffergröße von 1, dann verhält es sich eigentlich wie a BehaviorSubject: Das ist nicht ganz richtig; überprüfen dieser tolle Blogbeitrag auf Unterschiede zwischen diesen beiden. Zum Beispiel, wenn Sie ein abgeschlossenes abonnieren BehaviorSubject, erhalten Sie nicht den letzten Wert, sondern für a ReplaySubject(1) Sie erhalten den letzten Wert.

    – Welke

    30. Oktober 19 um 15:24 Uhr

  • Ich denke, ein ziemlich einfaches Beispiel, das Sie für das Wiederholungsthema erwähnen könnten, wäre ein „Chatroom“- oder Spiele-Lobby-Szenario, in dem Sie möchten, dass neue Teilnehmer die letzten 10 Nachrichten sehen.

    – James

    25. Februar 20 um 9:35 Uhr

Subjekt vs VerhaltenSubject vs ReplaySubject in Angular
Ricky Boyce

Eine praktische Zusammenfassung der verschiedenen beobachtbaren Typen, nicht intuitive Benennung, ich weiß, lol.

  • Subject – Ein Abonnent erhält darauf nur veröffentlichte Werte, nachdem das Abonnement abgeschlossen wurde.
  • BehaviorSubject – Neue Abonnenten erhalten den zuletzt veröffentlichten Wert ODER den Anfangswert sofort nach dem Abonnement.
  • ReplaySubject – Neue Abonnenten erhalten alle zuvor veröffentlichten Werte sofort nach dem Abonnement

  • 1-n veröffentlichte Werte? Wenn es also 2 veröffentlichte Werte gäbe, würde ein ReplaySubject -1 veröffentlichte Werte erzeugen???

    – Jason Cheng

    23. Juli 2020 um 5:58 Uhr

  • @JasonCheng nein, es ruft alle zuvor veröffentlichten Werte beim Abonnement ab, aktualisiere die Antwort 🙂

    – Ricky Boyce

    23. Juli 2020 um 20:54 Uhr


  1. Gegenstand: Beim Abonnieren erhält es immer die Daten, die nach dem Abonnement verschoben werden, dh vorherige gepushte Werte werden nicht empfangen.
const mySubject = new Rx.Subject();

mySubject.next(1);

const subscription1 = mySubject.subscribe(x => {
  console.log('From subscription 1:', x);
});

mySubject.next(2);

const subscription2 = mySubject.subscribe(x => {
  console.log('From subscription 2:', x);
});

mySubject.next(3);

subscription1.unsubscribe();

mySubject.next(4);

Bei diesem Beispiel ist hier das Ergebnis, das in der Konsole ausgegeben wird:

From subscription 1: 2
From subscription 1: 3
From subscription 2: 3
From subscription 2: 4

Beachten Sie, dass bei verspäteten Abonnements einige der Daten fehlen, die in den Betreff gepusht wurden.

  1. Themen wiederholen: kann helfen, indem Sie a Puffer der vorherigen Werte die an neue Abonnements ausgegeben werden.

Hier ist ein Anwendungsbeispiel für Wiederholungsthemen, bei denen a buffer of 2 previous values werden aufbewahrt und bei neuen Abonnements ausgegeben:

const mySubject = new Rx.ReplaySubject(2);

mySubject.next(1);
mySubject.next(2);
mySubject.next(3);
mySubject.next(4);

mySubject.subscribe(x => {
  console.log('From 1st sub:', x);
});

mySubject.next(5);

mySubject.subscribe(x => {
  console.log('From 2nd sub:', x);
});

Folgendes gibt uns das an der Konsole:

From 1st sub: 3
From 1st sub: 4
From 1st sub: 5
From 2nd sub: 4
From 2nd sub: 5
  1. Verhaltensthemen: ähneln Replay-Subjekten, geben aber nur den zuletzt ausgegebenen Wert oder einen Standardwert erneut aus, wenn zuvor kein Wert ausgegeben wurde:
const mySubject = new Rx.BehaviorSubject('Hey now!');

mySubject.subscribe(x => {
  console.log('From 1st sub:', x);
});

mySubject.next(5);

mySubject.subscribe(x => {
  console.log('From 2nd sub:', x);
});

Und das Ergebnis:

From 1st sub: Hey now!
From 1st sub: 5
From 2nd sub: 5

Bezug: https://alligator.io/rxjs/subjects/

  • Der Referenzartikel ist wirklich hilfreich

    – Dan

    26. September 21 um 15:22 Uhr

Die am meisten positiv bewertete Antwort ist eindeutig falsch, wenn sie behauptet, dass:

“Wenn Sie eine initialisieren ReplaySubject mit einer Puffergröße von 1, dann verhält es sich eigentlich wie a BehaviorSubject


Das ist nicht ganz richtig; überprüfen dieser tolle Blogbeitrag auf Unterschiede zwischen diesen beiden. Zum Beispiel, wenn Sie ein abgeschlossenes abonnieren BehaviorSubject, erhalten Sie nicht den letzten Wert, sondern für a ReplaySubject(1) Sie erhalten den letzten Wert.

Dies ist ein wichtiger Unterschied, der nicht übersehen werden sollte:

const behavior = new BehaviorSubject(null);
const replay = new ReplaySubject(1);

behavior.skip(1).subscribe(v => console.log('BehaviorSubject:', v));
replay.subscribe(v => console.log('ReplaySubject:', v));

behavior.next(1);
behavior.next(2);
behavior.complete();
behavior.subscribe(v => console.log('Late B subscriber:', v));

replay.next(1);
replay.next(2);
replay.complete();
replay.subscribe(v => console.log('Late R subscriber:', v));

Überprüfen Sie dieses Codebeispiel Hier was kommt von wieder ein toller Blogbeitrag zum Thema.

1642779914 81 Subjekt vs VerhaltenSubject vs ReplaySubject in Angular
HS-Progr

Aus: Randall Koutniks Buch „Build Reactive Websites with RxJS“. :

EIN Gegenstand ist ein Objekt, das ein turboaufgeladenes Observable ist. In seinem Kern, a Gegenstand verhält sich ähnlich wie ein normales Observable, aber jedes Abonnement ist mit derselben Quelle verbunden. Fächer sind auch Observer und haben Next-, Error- und Done-Methoden, um Daten gleichzeitig an alle Abonnenten zu senden. Denn Fächer Beobachter sind, können sie direkt in einen Subscribe-Aufruf geleitet werden, und alle Ereignisse des ursprünglichen Observable werden über das Subjekt an seine Subskribenten gesendet.

Wir können die verwenden ReplaySubject Geschichte zu verfolgen. EIN ReplaySubject zeichnet die letzten n Ereignisse auf und spielt sie jedem neuen Abonnenten vor. Zum Beispiel in Chat-Anwendungen. Wir können es verwenden, um die Aufzeichnung des vorherigen Chatverlaufs zu verfolgen.

EIN VerhaltenSubject ist eine vereinfachte Version der ReplaySubject. Der ReplaySubject gespeichert eine beliebige Anzahl von Ereignissen, die VerhaltenSubject zeichnet nur den Wert des letzten Ereignisses auf. Wann immer ein VerhaltenSubject ein neues Abonnement aufzeichnet, gibt es den letzten Wert an den Abonnenten sowie alle neuen Werte, die übergeben werden, aus VerhaltenSubject ist nützlich, wenn es um einzelne Zustandseinheiten geht, z. B. Konfigurationsoptionen.

1642779914 89 Subjekt vs VerhaltenSubject vs ReplaySubject in Angular
Bersling

Wie in einigen Beiträgen erwähnt, ist die akzeptierte Antwort seitdem falsch BehaviorSubject != ReplaySubject(1) und es ist nicht nur eine Vorliebe für den Codierungsstil.

In den Kommentaren werden oft die “Wächter” erwähnt und dort fand ich auch am häufigsten den Anwendungsfall für die Replay-Themen. Genauer gesagt, wenn Sie eine haben take(1) wie Szenario und Sie wollen nicht nur den Anfangswert nehmen.

Überprüfen Sie zum Beispiel Folgendes:

  ngOnInit() {
    const behaviorSubject = new BehaviorSubject<boolean>(null);
    const replaySubject = new ReplaySubject<boolean>(1);
    this.checkLoggedIn(behaviorSubject, 'behaviorSubject');
    this.checkLoggedIn(replaySubject, 'replaySubject');
    behaviorSubject.next(true);
    replaySubject.next(true);
  }

  checkLoggedIn($userLoggedIn: Observable<boolean>, id: string) {
    $userLoggedIn.pipe(take(1)).subscribe(isLoggedIn => {
      if (isLoggedIn) {
        this.result[id] = 'routed to dashboard';
      } else {
        this.result[id] = 'routed to landing page';
      }
    });
  }

mit dem Ergebnis:

{
  "behaviorSubject": "routed to landing page",
  "replaySubject": "routed to dashboard"
}

In diesen Fällen möchten Sie eindeutig a ReplaySubject! Arbeitscode: https://stackblitz.com/edit/replaysubject-vs-behaviorsubject?file=src%2Fapp%2Fapp.component.ts

Subjekt vs VerhaltenSubject vs ReplaySubject in Angular
Pramod Patil

     // ***********Subject  concept ***********
    let subject = new Subject<string>();


    subject.next("Eureka");
    subject.subscribe((data) => {
      console.log("Subscriber 1 got data >>>>> "+ data);
    });
    subject.subscribe((data) => {
      console.log("Subscriber 2 got data >>>>> "+ data);
    });

       // ********behaviour subject*********
    // Behavior subjects need a first value
let subject1 = new BehaviorSubject<string>("First value");


subject1.asObservable().subscribe((data) => {
  console.log("First subscriber got data behaviour subject>>>>> "+ data);
});
subject1.next("Second value")
  • Betreff – Ein Abonnent erhält darauf nur veröffentlichte Werte, nachdem das Abonnement abgeschlossen wurde.
  • BehaviorSubject – Neue Abonnenten erhalten den zuletzt veröffentlichten Wert ODER den Anfangswert sofort nach dem Abonnement.

.

577750cookie-checkSubjekt vs. VerhaltenSubject vs. ReplaySubject in Angular

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy