Warm streams

So far, we have been describing and discussing cold Observables and hot Observables, but there is a third kind: the warm Observable. A warm Observable can be thought of as being created as a cold Observable, but turning into a hot Observable under certain conditions. Let's look at such a case by introducing the refCount() operator:

// hot-cold-warm/warm-observer.js

const Rx = require("rxjs/Rx");

let warmStream = Rx.Observable.interval(1000).take(3).publish().refCount();
let start = new Date();

setTimeout(() => {
warmStream.subscribe(data => {
console.log(`subscriber 1 - ${new Date() - start}`,data);
});
}, 2000);

OK, so we started to use the operator publish(), and it looks like we are about to use our connect() operator and that we have a hot Observable, right? Well, yes, but instead of calling connect(), we call refCount(). This operator will warm our Observable up so that when the first subscriber arrives, it will act like a cold Observable. OK? That just sounds like a cold Observable, right? Let's have a look at the output first:

To answer the preceding question, yes, it's correct that it just behaves like a cold Observable; we aren't missing out on any emitted values. The interesting thing happens when we get a second subscriber. Let's add that second subscriber and see what the effects are:

// hot-cold-warm/warm-observable-subscribers.js

const Rx = require("rxjs/Rx");

let warmStream = Rx.Observable.interval(1000).take(3).publish().refCount();
let start = new Date();

setTimeout(() => {
warmStream.subscribe(data => {
console.log(`subscriber 1 - ${new Date() - start}`,data);
});
}, 1000);

setTimeout(() => {
warmStream.subscribe(data => {
console.log(`subscriber 2 - ${new Date() - start}`,data);
});

}, 3000);

Our second subscriber is added; now, let's have a look at what the result is:

What we can see from the results above is that the first subscriber is alone in receiving the number 0. When the second subscriber arrives, its first value is 1, which proves the stream has gone from acting like a cold Observable to a hot Observable. 

There is another way we can do warm Observables, and that is through using the share() operator. The share() operator can be seen as more of a smart operator that allows our Observable to go from cold to hot, depending on the situation. That can be a really great idea sometimes. So, there are the following situations for Observables:

  • Created as a hot Observable; the stream hasn't completed, and none of the subscribers are more than one
  • Falls back into being a cold Observable; any previous subscription has had time to end before a new subscription arrives
  • Created as a cold Observable; the Observable itself has had time to complete before the subscription happens

Let's try to show in code how the first bullet can happen:

// hot-cold-warm/warm-observable-share.js

const Rx = require("rxjs/Rx");

let stream$ = Rx.Observable.create((observer) => {
let i = 0;
let id = setInterval(() => {
observer.next(i++);
}, 400);

return () => {
clearInterval(id);
};
}).share();

let sub0, sub;

// first subscription happens immediately
sub0 = stream$.subscribe(
(data) => console.log("subscriber 0", data),
err => console.error(err),
() => console.log("completed"));

// second subscription happens after 1 second
setTimeout(() => {
sub = stream$.subscribe(
(data) => console.log("subscriber 1", data),
err => console.error(err),
() => console.log("completed"));
}, 1000);

// everything is unscubscribed after 2 seconds
setTimeout(() => {
sub0.unsubscribe();
sub.unsubscribe();
}, 2000);

The preceding code describes a situation where we defined a stream with a subscription that happens straight away. The second subscription happens after one second. Now, according to the definition of the share() operator, this means that the stream will be created as a cold Observable, but will, at the time of the second subscriber, be turned into a hot Observable, as there is a pre-existing subscriber and the stream has yet to complete. Let's inspect our output to verify that this is the case:

The first subscriber seems to be clearly alone in the values it gets. When the second subscriber arrives, it seems to share the producer, as it doesn't start from zero, but, rather, it starts listening where the first subscriber is.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.141.202.30