DEV Community

Benjamin Arambide
Benjamin Arambide

Posted on

Understanding RxJS: Cold and Hot Observables

In RxJS, observables are cold by default, meaning that each subscription to an observable creates an independent execution of the observable's logic. This is why you see the map operator's logic being executed for each subscription. Each subscriber gets its own independent stream of emissions from the source observable.

Cold Observables

A cold observable is one where the data producer (the logic inside the observable) is created anew for each subscriber. This means that if you subscribe to a cold observable multiple times, each subscription will re-execute the observable's logic independently.

Example of Cold Observable

import { of } from 'rxjs';
import { map } from 'rxjs/operators';

const source$ = of(1).pipe(
  map(value => {
    console.log('map called');
    return value * 2;
  })
);

source$.subscribe(value => console.log('Subscriber 1:', value));
source$.subscribe(value => console.log('Subscriber 2:', value));
Enter fullscreen mode Exit fullscreen mode

Output

map called
Subscriber 1: 2
map called
Subscriber 2: 2
Enter fullscreen mode Exit fullscreen mode

In this example, the map operator's logic is executed twice, once for each subscription.

When to use:

  • When you want each subscription to receive all the data from the beginning.
  • When you want to repeat the data for each new subscriber.
  • Examples: HTTP requests, mouse clicks, timer observables.

Hot Observables

A hot observable, on the other hand, shares a single execution of the observable's logic among all subscribers. Using operators like share, shareReplay, or publish can convert a cold observable into a hot observable.

Example of Hot Observable with shareReplay

import { of } from 'rxjs';
import { map, shareReplay } from 'rxjs/operators';

const source$ = of(1).pipe(
  map(value => {
    console.log('map called');
    return value * 2;
  }),
  shareReplay(1) // Shares the last emitted value with all subscribers
);

source$.subscribe(value => console.log('Subscriber 1:', value));
source$.subscribe(value => console.log('Subscriber 2:', value));

Enter fullscreen mode Exit fullscreen mode

Output

map called
Subscriber 1: 2
Subscriber 2: 2
Enter fullscreen mode Exit fullscreen mode

In this example, the map operator's logic is executed only once, and the result is shared among all subscribers.

When to use:

  • When you want subscribers to receive only values that are emitted after they subscribe.
  • When you don't want each subscriber to get its own independent stream of values.
  • Examples: WebSocket streams, mouse move events, stock tickers.

Choosing Between Hot and Cold Observables

  • Cold Observables are typically used when you want to ensure that each subscriber gets all the data and/or when the data source is created anew for each subscriber.

  • Hot Observables are useful when you want to share a single execution of the observable among multiple subscribers, or when you're dealing with data sources that are already producing events.

Top comments (0)