Уроки9. defer: фабрика на каждую подписку
Уроки · 09
9. defer: фабрика на каждую подписку
Проблема: значение зависит от момента подписки
Представьте: вы хотите создать Observable, который вернёт текущее время. Если написать of(Date.now()), время «заморозится» в момент создания Observable. Все подписчики получат одно и то же — даже если подписались спустя час.
Решение: defer
defer(factory) принимает функцию-фабрику. Она вызывается заново каждый раз, когда кто-то подписывается. Внутри можно вычислить актуальное значение или построить новый Observable.
defer(() => of(Date.now()))
// Каждый подписчик получит свежий Date.now()
Где это полезно
- Текущая дата, актуальный токен авторизации.
- Свежий HTTP-запрос: повторная подписка должна делать новый запрос, а не возвращать кэш.
- Любое значение, которое должно вычисляться в момент подписки, а не при создании.
Глоссарий
- Фабрика (factory) — функция, которая по требованию создаёт нечто новое. В
deferона создаёт Observable.
Что нужно сделать
- Внутри функции-фабрики первой строкой увеличьте счётчик:
calls++;. - Выведите
console.log('Factory call: ' + calls). - Вместо
of('TODO')вернитеof('Data ' + calls), чтобы значение зависело от номера вызова. - Ожидаемый порядок:
Sub A → Factory call: 1 → Data 1 → Sub B → Factory call: 2 → Data 2. Два подписчика — две независимые работы.
Решение 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
Нажмите на запуск, чтобы увидеть результат...