Javascript – How does the RxJs 5 share() operator work

javascriptrxjsrxjs5

Its not 100% clear for me how the RxJs 5 share() operator works, see here the latest docs. Jsbin for the question here.

If I create an observable with a series of 0 to 2, each value separated by one second:

var source = Rx.Observable.interval(1000)
.take(5)
.do(function (x) {
    console.log('some side effect');
});

And if I create two subscribers to this observable:

source.subscribe((n) => console.log("subscriptor 1 = " + n));
source.subscribe((n) => console.log("subscriptor 2 = " + n));

I get this in the console:

"some side effect ..."
"subscriptor 1 = 0"
"some side effect ..."
"subscriptor 2 = 0"
"some side effect ..."
"subscriptor 1 = 1"
"some side effect ..."
"subscriptor 2 = 1"
"some side effect ..."
"subscriptor 1 = 2"
"some side effect ..."
"subscriptor 2 = 2"

I thought each subscription would subscribe to the same Observable, but it does not seem to be the case! Its like the act of subscribing creates a completely separate Observable!

But if the share() operator is added to the source observable:

var source = Rx.Observable.interval(1000)
.take(3)
.do(function (x) {
    console.log('some side effect ...');
})
.share();

Then we get this:

"some side effect ..."
"subscriptor 1 = 0"
"subscriptor 2 = 0"
"some side effect ..."
"subscriptor 1 = 1"
"subscriptor 2 = 1"
"some side effect ..."
"subscriptor 1 = 2"
"subscriptor 2 = 2"

Which is what I would expect without the share().

Whats going on here, how does the share()operator work ? Does each subscription create a new Observable chain?

Best Answer

Be careful that you are using RxJS v5 while your documentation link seem to be RxJS v4. I don't remember specifics but I think that the share operator went through some changes, in particular when it comes to completion and resubscription, but don't take my word for it.

Back to your question, as you have shown in your study, your expectations do not correspond to the library design. Observables lazily instantiate their data flow, concretely initiating the dataflow when a subscriber subscribes. When a second subscriber subscribes to the same observable, another new dataflow is started as if it is was the first subscriber (so yes, each subscription creates a new chain of observables as you said). This is what is coined in RxJS terminology as a cold observable and that's the default behaviour for RxJS observable. If you want an observable which sends its data to the subscribers it has at the moment the data arrives, this is coined a hot observable, and one way to get a hot observable is to use the share operator.

You can find illustrated subscription and data flows here : Hot and Cold observables : are there 'hot' and 'cold' operators? (this is valid for RxJS v4, but most of it is valid for v5).