如何在角度5中执行缓存http get请求?

时间:2019-03-13 07:34:50

标签: angular angular5 angular-httpclient

    import { Injectable } from '@angular/core';
    import { HttpClient, HttpErrorResponse } from '@angular/common/http';
    import { Observable } from 'rxjs';
    import { catchError } from 'rxjs/operators';

    @Injectable()
    export class ApiService {

      constructor(private http: HttpClient) { }

      // get API request
      public apiGetRequest(url: any): Observable<any> {
        return this.http.get(url)
          .pipe(
            catchError(this.handleError('apiGetRequest'))
          );
      }
    }

我在rxjs 5.5.6版中使用了angular 5,我试图缓存多个http get请求。

4 个答案:

答案 0 :(得分:1)

这样就没有rxjs ‍♂️,但是您可以检查此answer

@Injectable()
export class CashingService {

  private __cach = {}
  isCashed(url: string) {
    return this.__cach[url];
  }

  getData(url: string) {
    return this.__cach[url]
  }

  setData(url) {
    return (data) => {
      if (data && (data instanceof Error) === false)
        this.__cach[url] = data
    };

  }

  reset() {
    this.__cach = {};
  }

}

注入缓存服务

@Injectable()
export class ApiService {

  constructor(private http: HttpClient , private _c:CachingService ) { }

  // get API request
  public apiGetRequest(url: any): Observable<any> {

    if (this._c.isCashed(url)){
     return of(this._c.getData(url));
    } else {
    return this.http.get(url)
      .pipe(
       tab(this._c.setData(url)),
       catchError(this.handleError('apiGetRequest'))
      );
    }

  }
}

答案 1 :(得分:1)

正确的方法如下:

private varName$: Observable<T>;

private _apiGetRequest():Observable<T>{
 return this.http.get('endpoint');
}
public apiGetRequest():Observable<T>{
 if(!this.varName$){
  this.varName$ = this._apiGetRequest().pipe(shareReplay(1));
 }
 return this.varName$
}

这样,私有观察者将保留最后发出的值

答案 2 :(得分:1)

这是我正在使用的缓存服务,它将数据存储在Redux存储中,但是很容易更改为所需的任何数据持有人。

@Injectable()
export class CacheManager {

  constructor(
    private store: NgRedux<IAppState>,
    private actions: GlobalActions) {
  }

  public get<T>(key: CacheKey, thisArg: any, dataRetriver: (...args: any[]) => T | Observable<T>, ...args: any[]): Observable<T> {
    if (this.isCached(key)) {
      return of(this.getFromCache<T>(key));
    }

    const data$: T | Observable<T> = dataRetriver.apply(thisArg, args);

    if (data$ instanceof Observable) {
      return data$.pipe(
        tap(result => this.addToCache(key, result))
      );
    }
    else {
      this.addToCache(key, data$);
      return of(data$);
    }
  }

  public clear(): void {
    this.store.dispatch(this.actions.clearCache());
  }

  private isCached(key: string): boolean {
    return this.cacheStorage[key] !== undefined;
  }

  private addToCache<T>(key: string, value: T): void {
    this.store.dispatch(this.actions.cache(key, value));
  }

  private getFromCache<T>(key: string): T {
    return <T>this.cacheStorage[key];
  }

  private get cacheStorage(): { [key: string]: any } {
    return this.store.getState().global.cache;
  }
}

和使用示例:

// call without cache:
this.service.loadPeriods(param1, param2)
  .pipe(...)
  .subscribe(...)

// call with cache ("periods" is a cache key):
this.cache.get("periods", this.service, this.service.loadPeriods, param1, param2)
  .pipe(...)
  .subscribe(...);

答案 3 :(得分:1)

  

您可以创建内部键/值对存储解决方案来缓存请求。   在这里,我为此使用 Map()

import { Injectable } from '@angular/core';
import { HttpEvent, HttpRequest, HttpHandler, HttpInterceptor, HttpResponse } from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { tap, shareReplay } from 'rxjs/operators';

@Injectable()
export class CacheInterceptor implements HttpInterceptor {
  private cache = new Map<string, any>();

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    if (request.method !== 'GET') {
      return next.handle(request);
    }

    const cachedResponse = this.cache.get(request.url);
    if (cachedResponse) {
      return of(cachedResponse);
    }

    return next.handle(request).pipe(
      tap(event => {
        if (event instanceof HttpResponse) {
          this.cache.set(request.url, event);
        }
      })
    );
  }
}
  

现在,您需要照顾缓存失效。每当数据更改时,您都需要使它们无效。