Die heiß/warm/kalt Terminologie wird immer verwirrend sein. Ich versuche der Temperaturmetapher zu entkommen, um genau zu verstehen, was unter der Haube passiert.
Also im Grunde sind alle (Rxjs) Observablen (mit Ausnahme der Themen) faul. Das heißt, wenn es keine Abonnenten (auch Beobachter genannt) gibt, wird kein Datenfluss (oder irgendetwas in der Tat) stattfinden. Sie finden eine illustrierte und genauere Erklärung der Subskription und der Datenflüsse, die sich hier im Abonnement abspielen: Hot and Cold observables : are there 'hot' and 'cold' operators?
share
gibt ein Observable zurück, so dass Observable auch faul ist. Der Produzent (der von der Verkettung des Betreibers spezifiziert wird) startet somit zum ersten Mal mit dem ersten Abonnement. Also egal, auf was Sie vor dem Abonnement klicken, nichts wird ausgeführt. Wenn Sie einmal abonniert haben, wird Ihr Producer ausgeführt und Ihr Beobachter/Abonnement generiert den Wert 1
.
Wie Sie in der verknüpften dargestellten Datenfluß sehen können, share
ist ein Alias für publish().refCount()
, wo publish
ist multicast(new Rx.Subject())
so Ob.fromEvent(button, 'click').scan(acc=>++acc,0)
ein Thema abonniert hat. Der wichtige Punkt hier ist, dass das Thema tatsächlich noch nicht abonniert hat, aber wenn Sie connect()
anrufen werden. Sobald das Subjekt abonniert hat, wird es alle Werte, die es erhält, an alle Beobachter, die es bei ihm registriert hat, weiterleiten in dem Moment, in dem der Wert ankommt. Dieses Verhalten wird als heißes Verhalten angesehen. Der verwirrende Teil ist, dass heiße Observable Observable sind und daher immer noch faul sind (mit Ausnahme von Fächern, die nicht faul sind).
Im Detail geht publish
eine verbindbare Observable zurück (immer noch faul). Wenn Sie es abonnieren, abonnieren Sie das oben genannte Thema. Aber solange Sie nicht connect()
tun, ist das Subjekt selbst nicht an der Quelle beobachtbar. Daher werden keine Daten fließen.
Um Sie davon zu überzeugen, ersetzen Sie Ihre codepen mit:
const Ob = Rx.Observable
const button = document.querySelector('#click')
const count$ = Ob.fromEvent(button, 'click')
.scan(acc=>++acc,0)
.publish();
setTimeout(()=>{
count$.subscribe(x=>console.log('sub1:',x))
},1000)
setTimeout(()=>{
count$.subscribe(x=>console.log('sub2:',x))
count$.connect();
},5000)
kurz So in obs.publish(); obs.subscribe(observer1)
, haben Sie Verbindung, bevor der Zustand nach obs | subject -> observer1
wo a-->b
b is subscribed to a
bedeutet. Es werden keine Daten fließen, da das Subjekt nur Werte weitergibt, die es empfängt, und es empfängt keine, da es keine Quelle abonniert hat. Wenn Sie connect()
haben, haben Sie den Status: obs -> subject -> observer1
. Daher wird obs
Producer starten, Wert an das Subjekt senden, das wiederum Werte an jeden Beobachter sendet, den es zum Zeitpunkt des Empfangs dieser Werte hat.
Ich bin nicht sehr vertraut mit RXJS, aber wo geben Sie an, dass eine heiße und nicht kalt beobachtbar ist? – paul
Ich denke, standardmäßig sollte Button klicken heiß sein, oder? Denn unabhängig davon, ob es sich um einen Abonnenten handelt, wird der Button immer noch angeklickt. Ich habe die Methode '.share()' verwendet, um sicherzustellen, dass es heiß ist. –