Use cases/In-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-запрос. После завершения кеш чистится — следующий запрос пойдёт в сеть свежим.