Her*_*sen 11 angular angular-httpclient
在我的Angular 5应用程序中,在应用程序的不同位置需要多次某个数据集(不经常更改).调用API后,结果将与Observable do运算符一起存储.这样我在我的服务中实现了HTTP请求的缓存.
我正在使用Angular 5.1.3和RxJS 5.5.6.
这是一个好习惯吗?还有更好的选择吗?
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);
    }
  }
}
And*_*tar 14
您的解决方案的问题在于,如果第一个呼叫在第一个呼叫到期时出现,则会创建新的http请求.我将如何做到这一点:
@Injectable()
export class FruitService {
  readonly fruits = this.http.get<any>('api/getFruits').shareReplay(1);
  constructor(private http: HttpClient) { }
}
更大的问题是当你有params并且你想根据params缓存.在这种情况下,你需要某种memoize功能,如lodash中的功能(https://lodash.com/docs/4.17.5#memoize)
您还可以cache为其实现一些内存中的运算符Observable,例如:
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}`);
}
还有另一种方法可以使用 shareReplay 和 Angular 5、6 或 7:创建一个服务:
import { Observable } from 'rxjs/Observable';
import { shareReplay } from 'rxjs/operators';
const CACHE_SIZE = 1;
private cache$: Observable<Object>;
get api() {
  if ( !this.cache$ ) {
    this.cache$ = this.requestApi().pipe( shareReplay(CACHE_SIZE) );
  }
  return this.cache$;
}
private requestApi() {
  const API_ENDPOINT = 'yoururl/';
  return this.http.get<any>(API_ENDPOINT);
}
public resetCache() {
  this.cache$ = null;
}
要直接在 html 文件中读取数据,请使用以下命令:
<div *ngIf="this.apiService.api | async as api">{{api | json}}</div>
在您的组件中,您可以像这样订阅:
this.apiService.api.subscribe(res => {/*your code*/})
| 归档时间: | 
 | 
| 查看次数: | 10294 次 | 
| 最近记录: |