2017-09-13 18 views
3

Ich habe einen Elternteil beobachtbar, der, sobald er einen Abonnenten hat, einen Lookup durchführt und einen einzelnen Wert ausgibt, dann vervollständigen.RxJS 5, Umwandlung eines Observablen in ein BehaviorSubject (?)

Ich möchte das in eine beobachtbare (oder Verhaltensthema oder was auch immer funktioniert), die das folgende tut: Sobald es mindestens einen Abonnenten hat, erhält es das Ergebnis von der beobachtbaren Eltern (einmal). Dann gibt er diesen Wert an alle seine Teilnehmer aus und gibt diesen einzelnen Wert auch an alle zukünftigen Teilnehmer aus, wenn sie sich anmelden. Es sollte mit diesem Verhalten fortfahren, selbst wenn seine Teilnehmerzahl auf Null fällt.

Es scheint, als sollte dies einfach sein. Hier ist, was nicht funktioniert hat:

theValue$: Observable<boolean> = parent$ 
.take(1) 
.share() 

Andere Dinge, die nicht funktioniert hat: publishReplay(), publish(). Etwas, das besser funktioniert:

theValue$ = new BehaviorSubject<boolean>(false); 

parent$ 
.take(1) 
.subscribe(value => theValue$.next(value)); 

Es gibt ein Problem mit diesem Ansatz ist, aber: parent$ abonniert wird, bevor theValue$ seinen ersten Teilnehmer bekommt.

Gibt es einen besseren Weg, damit umzugehen?

Antwort

4

shareReplay sollte das tun, was Sie wollen:

import 'rxjs/add/operator/shareReplay'; 
... 
theValue$: Observable<boolean> = parent$.shareReplay(1); 

shareReplay wurde in RxJS Version 5.4.0 hinzugefügt. Es gibt eine Referenzzählung zurück, die beobachtbar ist und die Quelle - parent$ - bei der ersten Subskription abonnieren wird. Abonnements, die nach Abschluss der Quelle erstellt werden, erhalten erneut wiedergegebene Benachrichtigungen.

shareReplay - und refCount im Allgemeinen - wird in einem Artikel, den ich kürzlich schrieb, genauer erklärt: RxJS: How to Use refCount.

+0

Dies scheint zu funktionieren! Ich werde ein bisschen damit spielen, um sicherzustellen, dass es keine Überraschungen gibt. Das sieht gut aus - ich wünschte nur, sie hätten dies zu den Dokumenten hinzugefügt, als sie es erstellt haben. Ich mag es nicht, als würde ich eine undokumentierte Funktion verwenden, die verschwinden könnte. Aber ich sehe es als im Changelog hinzugefügt, also vermute ich, dass es hier ist um zu bleiben. – Karptonite

+0

Es ist dort zu bleiben. Die Dokumente sind in Arbeit. Wie auch immer, es ist sehr nah an 'publishReplay (1) .refCount()' - der Unterschied ist subtil. – cartant

+0

Nach dem Lesen Ihrer sehr gründlichen Blog-Posts denke ich, dass ich hier eigentlich "publishLast(). RefCount" haben möchte, obwohl sie in der Praxis in meinem Fall funktional fast identisch sind. Danke noch einmal! – Karptonite

Verwandte Themen