BACK
Уроки42. shareReplay: общий источник плюс кэш
Уроки · 42

42. shareReplay: общий источник плюс кэш

shareReplay — multicast + кэш

shareReplay — это share с дополнительной памятью. Он не только делает источник общим, но и запоминает последние N значений. Поздний подписчик мгновенно получает кэшированные значения без повторного запуска источника.

http.get(...).pipe(shareReplay(1))
// первая подписка → один HTTP-запрос → ответ кэшируется
// вторая подписка (хоть через час) → мгновенно получает кэш

Конфигурация

Современная форма — shareReplay({ bufferSize, refCount }):

  • bufferSize: 1 — сколько последних значений хранить.
  • refCount: true — отключать источник, когда подписчиков нет.
  • refCount: false — источник держится «вечно» (или пока не сборщик мусора). Подходит для глобальных кэшей.

Осторожно с вечным кэшем

Кэшированное значение никогда не обновится автоматически. Если данные могут меняться, нужна стратегия инвалидации (новый источник, ключ, expiration).

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

  1. В request$.pipe(...) добавьте shareReplay({ bufferSize: 1, refCount: false }).
  2. Тест проверит: счётчик requests равен 1, оба подписчика получили данные.

Детерминированная проверка

В этой задаче проверка идет через виртуальное время TestScheduler. Если решение верное, в консоли появится только Test Passed!. Не добавляйте лишние console.log, иначе проверка провалится.

Решение spoiler · click to reveal
const { Observable, shareReplay } = Rx;

let requests = 0;

const request$ = new Observable(subscriber => {
  requests += 1;
  const subscription = cold('20ms a|', { a: 'Data' }).subscribe(subscriber);
  return () => subscription.unsubscribe();
});

const cached$ = request$.pipe(
  shareReplay({ bufferSize: 1, refCount: false })
);
script.ts // TypeScript
CONSOLE · Console Output
Нажмите на запуск, чтобы увидеть результат...