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);
}
}
}
推荐答案
您的解决方案的问题是,如果第 2 个调用在第 1 个未决的情况下出现,它会创建一个新的 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屋!