【问题标题】:Angular ObservablesAngular Observables
【发布时间】:2019-01-17 23:00:29
【问题描述】:

这可能是一个非常基本的问题,但我真的陷入了这种情况,似乎无法通过实验找出答案:

我正在对某些数据执行 http GET 请求。我必须在“组件”中显示这些数据,然后我必须“访问”这些数据(从 http 请求收到的数据)。

所以我必须将这些数据存储在两个点。我会订阅两次从 http GET 请求返回的 Observable 吗?或者我是否必须订阅一次,将响应保存在某处,然后从保存的数据馈送我的两个用例(组件和访问)。

如果我订阅两次,是否有可能丢失数据,因为第一次订阅触发了 http GET,而第二次订阅“来晚了”?

如果这似乎含糊不清,请告诉我,我也会插入一些代码。

我正在使用 @angular/core 7.0.0 和 rxjs 6.3.3。

【问题讨论】:

  • 你API的数据会经常变化吗?有没有变化?
  • 这取决于您的数据更改的频率,不是吗?此外,通常应存储参考数据,因为它们不太可能经常更改

标签: angular rxjs


【解决方案1】:

如果我订阅两次,是否有可能丢失数据,因为第一次订阅触发了 http GET,而第二次订阅“来晚了”?

这取决于你的 observable 是 “hot” 还是 “cold”。关于这个主题有很多资源。但基本上,hot 是指一个 observable 由多个订阅者共享,cold 是指为每个订阅者创建一个新的 observable。

Angular 的httpClient.get 给你一个 observable。这意味着,每次您订阅它时,都会触发一个新的 http 请求

但是将冷的 observable 转换为热的 observable 真的很容易。您可以使用share 运算符来完成。例如:

this.httpClient.get("https://google.com").pipe(share())

但是,这会导致“迟到的订阅者”错过通知。如果您有两个订阅者并希望他们都得到保证的通知,您可以使用shareReplay(1)

this.httpClient.get("https://google.com").pipe(shareReplay(1))

这将缓存最后一条通知并在订阅时将其提供给每个订阅者,确保您只调用一次 HTTP 并且每个订阅者都会获得结果。

【讨论】:

  • 非常感谢您的澄清。
【解决方案2】:

您最好的选择是创建一个与您的 HTTP 调用关联的BehaviorSubject。您使用一个函数启动 HTTP 调用,然后使用另一个函数订阅这些值。因此,如果您不想触发 HTTP 调用,并不总是如此。

例子:

...
// Service
private values: BehaviorSubject<any> = new BehaviorSubject<any>(null);

subscribeValues(): BehaviorSubject<number> {
    return this.values;
}

public getValues(): void {
    this.http.get(this.URL)
      .toPromise()
      .then(res => {
        this.values.next(res);
      });
}
...

...
// Component
ngOnInit() {
  this.myService.subscribeValues().subscribe(value => {
      // whatever
  });
  this.myService.getValues();
}

BehaviorSubject 将始终发出它在您订阅它时拥有的最后一个(或初始)值。因此,当您从任何组件订阅时,您将获得最后一个值,并且您可以从任何组件再次触发 API,并且订阅的任何内容都将被更新。

【讨论】:

    猜你喜欢
    • 2020-02-10
    • 1970-01-01
    • 1970-01-01
    • 2019-10-27
    • 2019-01-02
    • 2019-08-04
    • 2017-03-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多