Angular 5缓存HTTP服务API调用 [英] Angular 5 caching http service api calls

查看:144
本文介绍了Angular 5缓存HTTP服务API调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆