angular2缓存服务器响应

时间:2017-11-21 00:01:09

标签: angular rxjs observable

我需要在我的服务中缓存服务器响应。我检查了这个问题caching results with angular2 http service,在这里我找到了两种方法:1)Observable.share() - 但正如它在答案中所说的那样,#share运算符仅适用于第一个请求,当所有订阅都被提供并且您创建另一个订阅时,它将无法工作,它将生成另一个请求" 2)使用ReplaySubject工作不错,直到使用解析器(它创建新的请求)。这是我的plunker https://plnkr.co/edit/TiODzGyQtXepojf4oPgw你可以查看网络标签,当你从组件A导航到组件B时,两种方式都可以创建新的请求。任何想法如何解决这个问题?

我的服务

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import * as Rx from 'rxjs';
import { Http } from '@angular/http';
import { ReplaySubject } from 'rxjs/ReplaySubject';

@Injectable()
export class ContactsService {
  goals: ReplaySubject<Array<any>> = new ReplaySubject(1);
  constructor(private http: Http) {}
  get() {
    if (!this.goals.observers.length) {
      return this.http
        .get('https://jsonplaceholder.typicode.com/posts/1');
    }

    return this.goals;
  }

  get2() {
    return this.http
        .get('https://jsonplaceholder.typicode.com/posts/1').share();
  }
}

更新

对于受试者,您可以使用以下方法(由ehrencrona建议)

cache: ReplaySubject<Array<any>>

get() {
  if (!this.cache) {
    this.cache = new ReplaySubject(1) 
    this.http.get(url).subscribe(this.cache)
  }

  return this.cache
}

对于observable,你可以使用我发现的这种方法

observable: Observable<any>;
get() {
    if (!this.observable) {
      this.observable = this.http.get(url).publishReplay(1).refCount();
    }

    return this.observable;
  }

请注意.publishReplay(1).refCount()与.share()不同 - .share()它不会创建新请求

1 个答案:

答案 0 :(得分:3)

使用RxJS缓存获取值的标准模式如下:

cache: ReplaySubject<Array<any>>

get() {
  if (!this.cache) {
    this.cache = new ReplaySubject(1) 
    this.http.get(url).subscribe(this.cache)
  }

  return this.cache
}

cache实例存储已提取的值。当您开始时,未设置实例,这表示之前从未获取过值。当您第一次调用get()时,它将创建一个ReplaySubject并让它“回放”它从AJAX调用中获取的值,方法是让它订阅http.get返回的原始observable。

然后返回的值始终是缓存。

请注意,此模式解决了缓存时的常见问题:如果第二个调用者在第一个方法完成检索之前调用该方法,它仍然只会执行一次HTTP调用。如果你只是缓存了检索到的值而不是一个难以实现的可观察量。