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);

Zobacz przykład

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);

Zobacz przykład

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.