Уроки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).
Что нужно сделать
- В
request$.pipe(...)добавьтеshareReplay({ bufferSize: 1, refCount: false }). - Тест проверит: счётчик
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
CONSOLE · Console Output
Нажмите на запуск, чтобы увидеть результат...