Оператор общего доступа rxjs с синхронизированным кешем
Я пытаюсь реализовать кеширующий сетевой вызов HTTP, который выгружает результат из кеша через определенное время, поэтому я реализовал этот оператор:
export const cacheForMinutes = <T>(minutes?: number) => <T>(source: Observable<T>) => {
if (!(minutes && minutes > 0))
return source
return source.pipe(share<T>({
connector: () => new ReplaySubject(1),
resetOnComplete: () => timer(minutes * 60_000)
}))
}
Затем в моей службе я использую это так:
getDtoSingle(..., minutesToCache: number) {
return this.http.get(...).pipe(
map(...),
cacheForMinutes(minutesToCache)
)
}
Когда я наблюдаю за сетевыми вызовами с помощью инструментов разработчика Chrome, я вижу, что на самом деле он не кэширует результаты за указанное время, а каждый раз выполняет сетевой вызов. Что я здесь сделал не так?
1 ответ
Вам нужно будет кэшировать результат во внешней переменной, как вы сказали, и получить к нему доступ с помощью некоторого метода глубокого сравнения (например, с помощьюobject-hash
), а затем удалите его, когда это будет сделано. Пример:
import hash from 'object-hash'
const cache: Record<string, Observable<any>> = {}
export function getDtoSingle(query, minutesToCache: number) {
const q = hash(query)
return of(0).pipe(swichMap(()=>
cache[q] ?? (cache[q] = this.http.get(query).pipe(
finalize(()=>delete cache[q]),
map(...),
cacheForMinutes(minutesToCache)
))
))
}