Lessons9. defer: a factory on every subscription
Lessons · 09
9. defer: a factory on every subscription
The problem: the value depends on when you subscribe
Picture this: you want an Observable that returns the current time. Write of(Date.now()) and the time "freezes" at the moment the Observable is created. Every subscriber gets the same value — even one that subscribes an hour later.
The fix: defer
defer(factory) takes a factory function. It's called afresh every time someone subscribes. Inside, you can compute an up-to-date value or build a brand-new Observable.
defer(() => of(Date.now()))
// Every subscriber gets a fresh Date.now()
Where it's useful
- The current date, or an up-to-date auth token.
- A fresh HTTP request: re-subscribing should fire a new request, not replay a cached one.
- Any value that should be computed at subscription time, not at creation time.
Glossary
- Factory — a function that builds something new on demand. In
defer, it builds an Observable.
Your task
- Inside the factory function, make the first line bump the counter:
calls++;. - Log
console.log('Factory call: ' + calls). - Instead of
of('TODO'), returnof('Data ' + calls)so the value depends on the call number. - Expected order:
Sub A → Factory call: 1 → Data 1 → Sub B → Factory call: 2 → Data 2. Two subscribers — two independent runs.
Solution spoiler · click to reveal
const { defer, of } = Rx;
let calls = 0;
const request$ = defer(() => {
calls++;
console.log('Factory call: ' + calls);
return of('Data ' + calls);
});
console.log('Sub A');
request$.subscribe(value => console.log(value));
console.log('Sub B');
request$.subscribe(value => console.log(value)); script.ts
CONSOLE · Console output
Hit Run to see the result...