Angular - 服务中的可观察量

时间:2017-09-24 11:13:17

标签: angular rxjs

我对Angular场景很新,我开始从一些意想不到的行为中解脱出来。

我在IntegrationsService中有以下代码

queryList(): Observable<ApiList[]> {
    if(this.loadingApiList == true) {
      return Observable.of(this.queryListResult);
    }
    this.loadingApiList = true;
    return this._http
      .get('samples/apiList.json').map( (response: Response) => <ApiList[]> response.json())
      .do(data => {
        this.queryListResult = data;
      });
}

如何在路由的页面加载时停止执行此调用两次?

组件调用此方法并在导航中构建列表,另一个组件也为以下方法调用相同的服务:

getApiName(IT_ID:number) {
    console.log(this.queryListResult);
    let obj = this.queryListResult.find(o => o.IT_ID == IT_ID);
    if(obj) {
      return obj.IT_Name;
    }
    return false;
}

当我不使用路由时,这非常有效,但是当我使用路由时,getApiName会返回一个未定义的结果。

我也使用了resolve对象,确实解决了问题但是后来又对json文件进行了两次调用,这就是我使用的。

  resolve(route: ActivatedRouteSnapshot, state:RouterStateSnapshot):Observable<any>{
    return this._service.queryList() // We need this to finish first.
  }

我现在真的被困住了 - 我可以使用解决方案让它工作但是两次调用.json是浪费的。

这样做的正确方法是什么?

1 个答案:

答案 0 :(得分:1)

  

如何在路由的页面加载时停止执行此调用两次?

这种情况正在发生,因为您订阅了两次。 Observable是懒惰的,每次用.subscribe()调用它时,它都会开始执行:在你的情况下,它会触发一个网络请求。将.subscribe()视为.call()()视为函数:每次调用函数时,都会执行。

考虑到这一点,您遇到的行为是预期的。有不同的方法来解决这个问题,这些方法类似但根据您的用例略有不同;即。订阅和取消订阅的确切时间。一般来说,您正在寻找的内容称为multicasting

最简单的多播形式是使用the .shared() operator。来自official docs;但请注意重点(我的):

  

返回一个新的Observable,它可以多播(共享)原始的Observable。 只要至少有一个订阅者,此Observable将被订阅并发送数据。当所有订阅者都取消订阅时,它将取消订阅源Observable。因为Observable是多播,所以它使流变热。这是.publish().refCount()的别名。

您可能感兴趣的是创建BehvaiorSubject,因为它具有&#34;当前值&#34;的概念。那么你的API调用将不会返回任何内容,它只会触发请求。

这是一个概念验证:

export class Service {

  public data$ = new BehaviorSubject(null);

  public get() {
    this.http.get(`some/data`).subscribe(data => this.data$.next(data))
  }

}

null是订阅data$时每个订阅者将同步获得的值。你可以像这样使用它。

this.get()
this.data$.subscribe(data => /* ... */)

当然,你可以将它包装成更好的东西,甚至开始实现缓存等等。

一些有用的链接: