Angular 5缓存HTTP服务API调用 [英] Angular 5 caching http service api calls
问题描述
在我的Angular 5应用中,需要在应用中的不同位置多次重复某个特定数据集(不经常更改).调用API后,结果将用Observable do
运算符存储.这样,我就在服务中实现了HTTP请求的缓存.
In my Angular 5 app a certain dataset (not changing very often) is needed multiple times on different places in the app. After the API is called, the result is stored with the Observable do
operator. This way I implemented caching of HTTP requests within my service.
我正在使用Angular 5.1.3和RxJS 5.5.6.
I'm using Angular 5.1.3 and RxJS 5.5.6.
这是一个好习惯吗? 有更好的选择吗?
Is this a good practise? Are there better alternatives?
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/do';
@Injectable()
export class FruitService {
fruits: Array<string> = [];
constructor(private http: HttpClient) { }
getFruits() {
if (this.fruits.length === 0) {
return this.http.get<any>('api/getFruits')
.do(data => { this.fruits = data })
} else {
return Observable.of(this.fruits);
}
}
}
推荐答案
您的解决方案的问题在于,如果在第一个呼叫挂起的同时出现第二个呼叫,它将创建一个新的http请求.这是我的处理方式:
The problem with your solution is that if a 2nd call comes while a 1st one is pending, it create a new http request. Here is how I would do it:
@Injectable()
export class FruitService {
readonly fruits = this.http.get<any>('api/getFruits').shareReplay(1);
constructor(private http: HttpClient) { }
}
更大的问题是当您有参数并且想要基于参数进行缓存时.在这种情况下,您将需要某种memoize
函数,例如lodash的函数( https://lodash.com/docs/4.17.5#memoize )
the bigger problem is when you have params and you want to cache based on the params. In that case you would need some sort of memoize
function like the one from lodash (https://lodash.com/docs/4.17.5#memoize)
您还可以为Observable
实现一些内存中的cache
运算符,例如:
You can also implement some in-memory cache
operator for the Observable
, like:
const cache = {};
function cacheOperator<T>(this: Observable<T>, key: string) {
return new Observable<T>(observer => {
const cached = cache[key];
if (cached) {
cached.subscribe(observer);
} else {
const add = this.multicast(new ReplaySubject(1));
cache[key] = add;
add.connect();
add.catch(err => {
delete cache[key];
throw err;
}).subscribe(observer);
}
});
}
declare module 'rxjs/Observable' {
interface Observable<T> {
cache: typeof cacheOperator;
}
}
Observable.prototype.cache = cacheOperator;
并像这样使用它:
getFruit(id: number) {
return this.http.get<any>(`api/fruit/${id}`).cache(`fruit:${id}`);
}
这篇关于Angular 5缓存HTTP服务API调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!