Оператор общего доступа 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)
      ))
    ))
}

Другие вопросы по тегам