RxJS A to Z — Part 2
RxJS A to Z — Part 2: Hot vs Cold Observables, Schedulers, Practical Use Cases
Understanding this difference is crucial to know how an Observable "creates" data:
import { Observable } from 'rxjs';
const cold$ = new Observable(observer => {
console.log('Observable started');
observer.next(Math.random());
});
cold$.subscribe(val => console.log('Sub A:', val));
cold$.subscribe(val => console.log('Sub B:', val));
Result: Different random numbers
import { Subject } from 'rxjs';
const hot$ = new Subject();
hot$.subscribe(val => console.log('Sub A:', val));
hot$.next(Math.random());
hot$.subscribe(val => console.log('Sub B:', val));
hot$.next(Math.random());
Result: Sub B won't receive the first value because it subscribed late.
Schedulers allow controlling when and how an Observable performs emit/subscribe operations.
asyncScheduler
– like setTimeoutqueueScheduler
– synchronous, in orderasapScheduler
– Promise microtask import { of, asyncScheduler } from 'rxjs'; console.log('Before'); of(1, 2, 3, asyncScheduler).subscribe(val => console.log(val)); console.log('After');
Output:
Meaning: asyncScheduler executes in the next phase (like setTimeout)
fromEvent(searchInput, 'input') .pipe( map(e => e.target.value), debounceTime(300), distinctUntilChanged(), switchMap(query => http.get('/api/search?q=' + query)) ) .subscribe(results => renderResults(results));
fromEvent(button, 'click') .pipe( throttleTime(2000) ) .subscribe(() => { // Call API or do action console.log('Clicked!'); });
Result: After clicking, it will only allow another click after 2 seconds.
combineLatest
– returns latest values when any observable emitsforkJoin
– waits until all completezip
– combines streams in order combineLatest([ of(1), interval(1000).pipe(take(3)) ]).subscribe(console.log);