Angular 2,共享服务中的并发http http可观察

时间:2016-04-14 12:55:05

标签: 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请求而不是返回缓存数据。 有人可以建议我如何避免这种副作用吗?

2 个答案:

答案 0 :(得分:3)

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

将其与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(...),但没有技术原因。他们认为它更易于维护。

答案 1 :(得分:1)

您必须在bootstrap方法中声明您的服务:

bootstrap(AppComponent, [SharedService]);

该服务只会实例化一次(单身),因此它可以解决您的问题。