RxJS. Простой кэш HTTP запроса с параметром
Кэш через 2 pipe оператора
- publishReplay(1) - буфер в одно сообщение. Каждый новый подписчик получит последний результат.
- refCount() - автоматически вызывет методы
connect()
, если появляются подписчки иunsubscribe()
, когда подписчиков не остаётся.
/** cached data */
private _cache: Observable<WhateverResponse>;
...
getData(): Observable<WhateverResponse> {
if (!this._cache) {
this._cache = this._http.get('url').pipe(
publishReplay(1),
refCount()
);
}
return this._cache;
}
Для хранения кэша отдельных запросов предлагается использовать Map
с ключами, которые являются параметрами запросов. Если используется объект параметров, то лучше его сериализовать в строку, из-за того, что объекты сравниваются по ссылке. Пример
{ a: '1'} == { a: '1' } // вернёт false
JSON.stringify({ a: '1'}) === JSON.stringify({ a: '1' } ) // вернёт true
Пример реализации:
/** http cache map */
private _instanceCache = new Map<string, Observable<TProductInstanceListResponse>>();
...
/**
* Product instance list
*/
getInstanceList(params: EntityListParams = {}): Observable<TProductInstanceListResponse> {
const key = JSON.stringify(params);
if (!this._instanceCache.has(key)) {
const response = this._http.get('instance', params).pipe(
publishReplay(1),
refCount()
);
this._instanceCache.set(key, response);
}
return this._instanceCache.get(key);
}
Для более сложных случаев рекомендуется библиотека cashew