Egor Panok

Full Stack JavaScript Developer

RxJS: Cold vs Hot Observables

January 06, 2019 - 3 min read

Cold

RxJS: Cold vs Hot Observables

Observables can be split into two main groups - Cold and Hot Observables. The difference of Cold and Hot Observables is like the difference between YouTube videos and YouTube live streams or TV broadcasts. Cold Observables are similar to YouTube videos which you can open anytime you’d like and start from the beginning. Hot Observables are like YouTube live streams or TV broadcasts which start when the hosts decide to start them, then you can join anytime but nobody will wait for you - you’ll watch it from the time you join.

Let’s show it by the following example.

Cold Observables

Suppose we have an Observable producing some values over time (to emulate creating new data we’ll generate new random integer numbers):

const observable = Observable.create(observer => {
    console.log("Observable is alive")

    const randomInt = () => Math.floor(Math.random() * 100)

    setTimeout(() => {
        observer.next({ name: "Event 1", value: `${randomInt()}` })
    }, 1000)

    setTimeout(() => {
        observer.next({ name: "Event 2", value: `${randomInt()}` })
    }, 2000)

    setTimeout(() => {
        observer.next({ name: "Event 3", value: `${randomInt()}` })
    }, 3000)
})

Then let’s create two observers:

// OBSERVER A
setTimeout(() => {
    observable.subscribe(data => {
        console.log(
            `Event '${data.name}' from Observable to Observer A. Value: ${data.value}`
        )
    })
}, 0)

// OBSERVER B
setTimeout(() => {
    observable.subscribe(data => {
        console.log(
            `Event '${data.name}' from Observable to Observer B. Value: ${data.value}`
        )
    })
}, 3000)

As we can notice in console, observer produces new data for each observer and it does it only when new subscription is created.

Cold Observable And Two Observers

Result in the console: Cold Observable and Two Observers

Notice that the observable goes alive twice and the produced values are different for each observer.

Now, how can we convert this Cold Observable into the Hot one? Well, there are two options.

Converting a Cold Observable into a Hot Observable

We can convert any Cold Observable into a Hot one by means of {share} operator.

import { share } from "rxjs/operators"

//....

// Here's the conversion from Cold to Hot
const sharedObservable = observable.pipe(share()) // using the observable from the previous example

const sharedObservable = observable.pipe(share())

// OBSERVER A
setTimeout(() => {
    sharedObservable.subscribe(data => {
        console.log(
            `Event '${data.name}' from Observable to Observer A. Value: ${data.value}`
        )
    })
}, 0)

// OBSERVER B
setTimeout(() => {
    sharedObservable.subscribe(data => {
        console.log(
            `Event '${data.name}' from Observable to Observer B. Value: ${data.value}`
        )
    })
}, 3000)

Here is the result in console:

Hot Observable And Two Observers

Result in the console: Hot Observable and Two Observers

Notice the following:

  1. the Observable goes alive just once
  2. the Observer B joins the broadcast only before Event 3 is emitted
  3. both observers receive the same value (from Event 3).

Hot Observables in the Wild

The most of the operators in RxJS return Hot Observables. Let’s pick the {fromEvent} operator.

import { Observable } from "rxjs/Observable"
import { fromEvent } from "rxjs/Observable/fromEvent"

// Observable from mouseMove
const mouseMoveObservable = fromEvent(document, "mousemove")

setTimeout(() => {
    mouseMoveObservable.subscribe((e: any) => {
        console.log(`Observer A: ${e.clientX} : ${e.clientY}`)
    })
    mouseMoveObservable.subscribe((e: any) => {
        console.log(`Observer B: ${e.clientX} : ${e.clientY}`)
    })
    mouseMoveObservable.subscribe((e: any) => {
        console.log(`Observer C: ${e.clientX} : ${e.clientY}`)
    })
    mouseMoveObservable.subscribe((e: any) => {
        console.log(`Observer D: ${e.clientX} : ${e.clientY}`)
    })
}, 2000)

{fromEvent} operator returns a hot Observable

**{fromEvent}** operator returns a hot Observable

Conclusion

Working with RxJS requires understanding the difference between Cold and Hot Observables. A good metaphor for remembering it is the comparison to YouTube videos and TV broadcasts.

Happy Coding!


Written by Egor Panok, full stack JavaScript Developer who loves building useful things. Follow him on Twitter

© 2020, Egor Panok, Full Stack JavaScript Developer