BACK
Use casesIn-flight deduplication — один запрос на один ключ
Use cases · 29

In-flight deduplication — один запрос на один ключ

Паттерн

Два компонента почти одновременно запрашивают пользователя с id=42. Обычный кеш ещё не успел заполниться (первый ответ не пришёл) — и backend получает два одинаковых запроса. Решение: кешировать не результат, а сам in-flight Observable до его завершения.

Какую проблему решаем

Это race window — короткое окно между «запрос отправлен» и «ответ получен», когда обычный response-cache бесполезен. Ручной Map<id, Promise> часто забывает удалять ключ при error/complete, и тогда повторный запрос навсегда заблокирован.

Операторы и зачем они нужны

  • defer — HTTP-вызов запускается только при первой подписке. Это lazy создание side effect.
  • shareReplay({ bufferSize: 1, refCount: true }) — второй подписчик получает тот же запрос и тот же ответ.
  • finalize — критически важен. Удаляет ключ из in-flight Map после complete/error/unsubscribe. Без него — утечка ключей.

Подводные камни

  • Без finalize ошибка оставит «битый» ключ в Map навсегда. Повторный запрос будет всегда возвращать ошибку из кеша.
  • refCount: false — request продолжит работать даже если все подписчики ушли. Для HTTP это иногда ок, для WebSocket опасно.
  • Ключ должен включать ВСЕ параметры запроса (не только id, но и фильтры, headers). Иначе разные запросы попадут в один кеш.

Что в итоге получаем

Параллельные подписчики разделяют один HTTP-запрос. После завершения кеш чистится — следующий запрос пойдёт в сеть свежим.

script.ts // TypeScript
CONSOLE · Console Output
Нажмите на запуск, чтобы увидеть результат...