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

查看:21
本文介绍了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);
    }
  }
}

推荐答案

您的解决方案的问题是,如果第 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屋!

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