BACK
Уроки9. defer: фабрика на каждую подписку
Уроки · 09

9. defer: фабрика на каждую подписку

Проблема: значение зависит от момента подписки

Представьте: вы хотите создать Observable, который вернёт текущее время. Если написать of(Date.now()), время «заморозится» в момент создания Observable. Все подписчики получат одно и то же — даже если подписались спустя час.

Решение: defer

defer(factory) принимает функцию-фабрику. Она вызывается заново каждый раз, когда кто-то подписывается. Внутри можно вычислить актуальное значение или построить новый Observable.

defer(() => of(Date.now()))
// Каждый подписчик получит свежий Date.now()

Где это полезно

  • Текущая дата, актуальный токен авторизации.
  • Свежий HTTP-запрос: повторная подписка должна делать новый запрос, а не возвращать кэш.
  • Любое значение, которое должно вычисляться в момент подписки, а не при создании.

Глоссарий

  • Фабрика (factory) — функция, которая по требованию создаёт нечто новое. В defer она создаёт Observable.

Что нужно сделать

  1. Внутри функции-фабрики первой строкой увеличьте счётчик: calls++;.
  2. Выведите console.log('Factory call: ' + calls).
  3. Вместо of('TODO') верните of('Data ' + calls), чтобы значение зависело от номера вызова.
  4. Ожидаемый порядок: 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 // TypeScript
CONSOLE · Console Output
Нажмите на запуск, чтобы увидеть результат...