Subject und BehaviorSubject: zwei Brüder in der Welt der reaktiven Programmierung
\n\nWenn Sie jemals auf Stack Overflow die Diskussion „What is the difference between Subject and BehaviorSubject?“ gesehen haben, dann wissen Sie: Dieses Thema sammelt tausende von Aufrufen. Und das ist kein Wunder – es ist eine dieser Fragen, die früher oder später vor jedem Entwickler steht, der mit RxJS in TypeScript arbeitet.
\n\nStellen Sie sich vor, Sie verwalten eine Live-Datenübertragung. Subject ist wie ein offenes Mikrofon: Wer zuerst abonniert, bekommt alles, was danach gesagt wird. BehaviorSubject hingegen ist ein Mikrofon, das immer den letzten Satz speichert und ihn sofort einem neuen Zuhörer wiederholt. Spüren Sie den Unterschied?
\n\nIn diesem Artikel wiederholen wir nicht einfach die Dokumentation. Wir analysieren reale Anwendungsfälle, zeigen Codebeispiele in TypeScript und geben klare Entscheidungsregeln. Los geht's!
\n\nWas ist Subject in TypeScript?
\n\nSubject ist ein spezieller Typ von Observable, der gleichzeitig auch ein Observer ist. Er kann Daten über die Methode next() empfangen und an alle Abonnenten verteilen. Es gibt jedoch eine wichtige Nuance: Subject speichert keine vorherigen Werte.
Ein einfaches Beispiel in TypeScript:
\n\nimport { Subject } from 'rxjs';\n\nconst subject = new Subject<string>();\n\n// Abonnieren, nachdem die Daten bereits gesendet wurden\nsubject.next('Erste Nachricht');\nsubject.next('Zweite Nachricht');\n\n// Dieser Abonnent erhält nichts\nsubject.subscribe({\n next: (value) => console.log('Abonnent:', value)\n});\n\n// Dies wird jedoch sichtbar sein\nsubject.next('Dritte Nachricht');\n\n\nWas wird in der Konsole ausgegeben? Nur „Abonnent: Dritte Nachricht“. Die ersten beiden Nachrichten sind für diesen Abonnenten für immer verloren. Dieser Effekt wird als „Kaltstart“ bezeichnet – Sie erhalten nur die Daten, die nach dem Abonnement gesendet wurden.
\n\nBehaviorSubject: wenn man sich an die Vergangenheit erinnern muss
\n\nBehaviorSubject ist dasselbe wie Subject, jedoch mit einer Superkraft: Es speichert immer den letzten Wert und gibt ihn sofort an einen neuen Abonnenten bei der Anmeldung weiter. Eine zwingende Voraussetzung ist die Angabe eines Anfangswerts.
\n\nimport { BehaviorSubject } from 'rxjs';\n\nconst behaviorSubject = new BehaviorSubject<string>('Anfangswert');\n\n// Abonnieren – sofort den letzten Wert erhalten\nbehaviorSubject.subscribe({\n next: (value) => console.log('Erster Abonnent:', value)\n});\n\nbehaviorSubject.next('Erstes Update');\nbehaviorSubject.next('Zweites Update');\n\n// Dieser Abonnent erhält sofort 'Zweites Update'\nbehaviorSubject.subscribe({\n next: (value) => console.log('Zweiter Abonnent:', value)\n});\n\n\nAusgabe in der Konsole:
\nErster Abonnent: Anfangswert\nErster Abonnent: Erstes Update\nErster Abonnent: Zweites Update\nZweiter Abonnent: Zweites Update\n\n\nSehen Sie? Der zweite Abonnent erhielt sofort den letzten Wert, obwohl er sich später angemeldet hat. Dies ist der entscheidende Unterschied zwischen BehaviorSubject und Subject.
\n\nVergleich von Subject und BehaviorSubject: Tabelle der Unterschiede
\n\nFassen wir alle Unterschiede in einer übersichtlichen Tabelle zusammen, die Ihnen bei einem Vorstellungsgespräch oder in einem realen Projekt nützlich sein wird.
\n\n- \n
- Anfangswert: Subject – nein. BehaviorSubject – zwingend erforderlich. \n
- Speicherung des letzten Werts: Subject – speichert nicht. BehaviorSubject – speichert und gibt ihn an neue Abonnenten weiter. \n
- Verhalten bei später Anmeldung: Subject – überspringt alle vorherigen Ereignisse. BehaviorSubject – gibt den letzten Wert aus. \n
- Verwendung mit Angular: Subject – für Ereignisse (Klicks, Timer). BehaviorSubject – für Zustände (Benutzerdaten, Einstellungen). \n
- Methode getValue(): Subject – nicht vorhanden. BehaviorSubject – vorhanden, gibt den aktuellen Wert synchron zurück. \n