What is the use case for cold observables? What is the use case for cold observables? javascript javascript

What is the use case for cold observables?


First of all, I invite you to review Hot and Cold observables : are there 'hot' and 'cold' operators? to make sure you have a thorough understanding of hot vs. cold.

Cold observables allow for lazyness of producers, and this is a very desirable feature. It is a waste to produce values (production could be expensive) when there is no use made of those values (no consumers). As such cold observables are the building block... from which more often hot observables are derived.

As such the most common use case for cold observables is to lazily derive hot observables. If you think about it, you need to programatically construct these hot observables somehow. One way is to use subjects (you then are the producer). The other way is to derive them from other preexisting observables through operators, preexisting observables which are also derived from others etc.. At the end of the chain, you should find Rx.Observable.create and that is a cold observable.

You use cold observable when you need lazyness (starting producing values only when there are consumers, or controlling the start of the producing process). For example, defer allows you to start a producer only when there is a consumer. It can be used when you have for example a hot observable but you are not ready yet to listen to it.

You also need cold observables when you need to reproduce a value-producing process (every new subscriber will restart the same exact process). This is for example the case for testing purposes, where you want to use the exact same sequence several times but with different consumers and at different times.

In the end, the question sounds more like a philosophical one. You have two tools at your disposal, what matters is understand what you need, what you have, and which works for your use case.


The core of the answer lies in Ben Lesh's laconic summary:

TL;DR: You want a HOT observable when you don’t want to create your producer over and over again.

In direct answer to the question "What's a case where you would prefer or use a cold observable over a hot one?", I'll offer both a general answer and a specific example.

Generally, it is far more convenient to use a cold observable to model streams that are created each time they are required than to create a hot one and try to wrangle it.

Specifically, consider the following trivial example. Say you want to respond to a click on a button by counting down from 10. If the button is clicked again during the countdown, it starts again at 10. If click$ models the button events, you might have something like this:

const subscription = click$  .flatMapLatest(_ => Rx.Observable.interval(1000).take(10))  .select(x => 10 - x)  .subscribe(x => console.log('clicked: ' + x));

Consider how this would be modelled without a cold observable. How would you:

  1. Initialize a stream in advance so that appropriate values were available when required?
  2. Avoid having to deal with the fraction of a second between the interval ticks and the time of your subscription?
  3. Deal with ordinals that can start at any number rather than just 1?
  4. Manage clean up logic for the stream?

1 and 3 can be addressed pretty easily, but 2 and 4 are nasty.

In answer to your second question "Is it laziness?" I would argue that it is not. A cold observable can leave it until the moment of subscription to produce its values. A hot observable can leave it until the moment of subscription to hook the appropriate events. They are both lazy in their own way (or at least, can be). The key difference lies in what Ben Lesh said: do you want to create a producer each time? And sometimes, you really do.


What's a case where you would prefer or use a cold observable over a hot one?

I hope I'm not stating the obvious, but any situation where you want to access all values (or some subset arrived at by filtering the complete set) from an observable's history.

The first example that comes to mind is averaging all of a student's test scores, not just the scores that have arrived after you've subscribed.