caching - Angular 2,共享服务http observable中的并发

标签 caching service concurrency angular

我有一个共享服务(从 this 建议开始)在第一次 http 请求后缓存并返回一些数据:

export class SharedService {
  constructor(private http:Http) {
  }

  getData() {
    if (this.cachedData) {
      return Observable.of(this.cachedData);
    } else {
      return this.http.get(...)
            .map(res => res.json())
            .do((data) => {
              this.cachedData = data;
            });
    }
  }
}

我的问题是我在同一个模板中有一些指令和组件同时初始化并且每个都同时调用(在 ngInit 函数内)getData 方法(所有这些都在第一个成功之前)等等该服务启动许多 http 请求而不是返回缓存的数据。 有人可以建议我如何避免这种副作用吗?

最佳答案

您的解决方案并未涵盖所有情况。

将其与我在 https://stackoverflow.com/a/36291681/217408 中的方法进行比较

getData() {
    if(this.data) {
      // if `data` is available just return it as `Observable`
      return Observable.of(this.data); 
    else if(this.observable) {
      // if `this.observable` is set then the request is in progress
      // return the `Observable` for the ongoing request
      return this.observable;
    } else {
      // create the request, store the `Observable` for subsequent subscribers
      this.observable = this.http.get('/someUrl')
          .map(res => res.json())
          .do(val => {
            this.data = val;
            // when the cached data is available we don't need the `Observable` reference anymore
            this.observable = null;
          })
          // make it shared so more than one subscriber can get the result
          .share();
      return this.observable;
    }
}

在请求未返回之前,您需要将从第一个请求创建的 Observable 返回到后续请求,直到第一个请求完成。

https://stackoverflow.com/a/36296015/217408还展示了一种有趣的方法,但有一个小缺点(取决于您的要求),即请求无法取消。

同时确保您仅将共享服务注册为提供者一次,如@MichaelD 所述。

Angular 团队建议使用根组件的 providers: [...] 列表而不是 bootstrap(...) 但没有技术原因。他们认为它更易于维护。

关于caching - Angular 2,共享服务http observable中的并发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36623788/

相关文章:

caching - 使用 zrange 按时间段查询 Redis 时间序列

ruby-on-rails - 用于个性化新闻提要的 Rails 缓存技术

grails - Grails Controller 和服务中的线程池

c# - WCF 到数据库连接

java - java中的并发有序列表

ruby-on-rails - 如何防止 Rails 中的浏览器页面缓存

javascript - 结合 _.memoize 和 _.throttle 来限制函数调用并在时间窗口内缓存结果?

java - Activity 与 GCMListenerService Android 通信

java - JFrame中如何运行2个线程

java - 带有 lambda 的 foreach 是否容易出现商品化错误