Zimne kontra gorące Obserwacje
Observables
można podzielić na dwie główne grupy: gorące i zimne. Zacznijmy od zimnego Observable
.
const obsv = new Observable(observer => {
setTimeout(() => {
observer.next(1);
}, 1000);
setTimeout(() => {
observer.next(2);
}, 2000);
setTimeout(() => {
observer.next(3);
}, 3000);
setTimeout(() => {
observer.next(4);
}, 4000);
});
// Subscription A
setTimeout(() => {
obsv.subscribe(value => console.log(value));
}, 0);
// Subscription B
setTimeout(() => {
obsv.subscribe(value => console.log(`>>>> ${value}`));
}, 2500);
W powyższym przypadku abonent B subskrybuje 2000 ms po abonencie A. Jednak abonent B zaczyna otrzymywać wartości takie jak abonent A tylko przesunięty czasowo. To zachowanie jest określane jako cold Observable
. Użyteczną analogią jest oglądanie wcześniej nagranego wideo, takiego jak na Netflix. Naciskasz Play i film zaczyna się od początku. Ktoś inny może rozpocząć odtwarzanie tego samego filmu we własnym domu 25 minut później.
Z drugiej strony istnieje również usługa, która przypomina bardziej występ na żywo. Od samego początku uczestniczysz w występach na żywo, ale ktoś inny może spóźnić się na 25 minut. Zespół nie zacznie grać od początku, a spóźniony musi zacząć oglądać występ z miejsca, w którym się znajduje.
Powyższy przykład jest zimnym Observable
, podczas gdy przykład, który używavalueChanges
jest gorącym Observable
.
Konwersja z zimnych Observable na gorące Observable
Przydatną metodą w RxJS API jest metoda publish
. Ta metoda przyjmuje zimne Observable
jako źródło i zwraca instancję ConnectableObservable
. W tym przypadku będziemy musieli jawnie wywołać connect
na naszym gorącymObservable
, aby rozpocząć nadawanie wartości swoim subskrybentom.
const obsv = new Observable(observer => {
setTimeout(() => {
observer.next(1);
}, 1000);
setTimeout(() => {
observer.next(2);
}, 2000);
setTimeout(() => {
observer.next(3);
}, 3000);
setTimeout(() => {
observer.next(4);
}, 4000);
}).publish();
obsv.connect();
// Subscription A
setTimeout(() => {
obsv.subscribe(value => console.log(value));
}, 0);
// Subscription B
setTimeout(() => {
obsv.subscribe(value => console.log(` ${value}`));
}, 2500);
W powyższym przypadku występ na żywo zaczyna się od 1000ms
, subskrybent A przybył do sali koncertowej w0s
, aby uzyskać dobre miejsce, a nasz abonent B przybył na występ na 2500ms
i przegapił kilka piosenek.
Inną przydatną metodą pracy z gorącym Observables
zamiastconnect
jest refCount
. Jest to metoda automatycznego łączenia, która rozpocznie nadawanie, gdy tylko pojawi się więcej niż jeden subskrybent. Analogicznie zatrzyma się, jeśli liczba subskrybentów osiągnie wartość 0; innymi słowy, jeśli wszyscy uczestnicy wyjdą, strumień się zatrzyma.