The hot/warm/cold terminology is always going to be confusing. I try to escape the temperature metaphor to understand exactly what's happening under the hood.
So basically, all (Rxjs) observables (with the exception of subjects) are lazy. That means that if there is no subscribers (also termed observers), there will be no data flow (or anything in fact). You will find an illustrated and more precise explanation of the subscription and data flows happening on subscription here : Hot and Cold observables : are there 'hot' and 'cold' operators?
share
returns an observable, so that observable is also lazy. The producer (speficied by your operator chaining) will hence start for the first time on the first subscription. So no matter on much you click before subscription, nothing is executed. When you have subscribed once, your producer is executed and your observer/subscription produces the value 1
.
As you can see in the linked illustrated data flow, share
is an alias for publish().refCount()
, where publish
is multicast(new Rx.Subject())
so Ob.fromEvent(button, 'click').scan(acc=>++acc,0)
has a subject subscribed to it. The important point here is that the subject has actually not subscribed YET, but will be when you will call connect()
. Once the subject has subscribed, it will pass on any values it receives to any observers it has registered on him at the moment the value arrives. It is that behaviour that is considered a hot behaviour. The confusing part is that hot observables are observables and hence are still lazy (EXCEPT subjects which are not lazy).
Going into details, publish
returns a connectable observable (still lazy). When you subscribe to it, you are subscribing to the aforementioned subject. But as long as you don't do connect()
, that subject is not itself subscribed to the source observable. Hence no data will flow.
To convince you of this, replace your codepen with :
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)
So in short in obs.publish(); obs.subscribe(observer1)
, you have before connection the following state obs | subject -> observer1
where a-->b
means b is subscribed to a
. No data will flow because the subject only passes on values it receives, and it is not receiving any, being not subscribed to any source.
When you connect()
you have the state : obs -> subject -> observer1
. Hence obs
producer will start, send value to the subject which sends in turn values to any observer it has at the moment of reception of those values.