【问题标题】:RxJs: Update observables inside a subscription correctlyRxJs:正确更新订阅中的 observables
【发布时间】:2021-10-23 18:15:09
【问题描述】:

我想知道如何在不触发许多事件的情况下更新订阅中的 observable。

在这个例子中,我订阅了area: Observable<Area>,如果区域发生变化,我想更新theme: Observable<Theme>distinctUntilChanged() 应该只在值发生变化时才触发订阅,但每次 area 更新时,theme 的更新量都会增加一。

  observeArea(): void {
    this.area
    .pipe(distinctUntilChanged()) 
    .subscribe(area => {
      this.themeService.updateTheme({primaryColor: area.color}); // should happen only once per area change
    })
  }

是否有任何“正确”的方式来做到这一点,而不会触发无休止的主题更新?

【问题讨论】:

  • area 似乎是一个对象,如果area 是不可变的distinctUntilChanged 应该可以正常工作
  • 你只是想观察area.color吗?
  • 您必须通过对象比较来观察 distinctUntilChanged,如果您要发出一个新对象,即使所有值都相同,它也是一个不同的对象。

标签: javascript angular typescript rxjs observable


【解决方案1】:

我认为问题可能出在您更新主题的方式上。

如果您尝试通过调用observeArea() 方法来更新主题。

每次调用该方法时,都会创建一个新订阅。 事件将传递给每个订阅。因此,每次调用该方法时,都会增加一个订阅。

解决方案

  1. 使用async 管道
area$!: Observable<any>;
observeArea(): void {
  this.area$ = this.area
  .pipe(
    distinctUntilChanged(),
    tap(area => this.themeService.updateTheme({primaryColor: area.color});)
   )
}

在 html 中使用 area$ | async 订阅。 示例:

<ng-container *ngIf="area$ | async">...</ng-container>
  1. 否则,您应该在每次订阅完成后退订
observeArea(): void {
    const sub = this.area
    .pipe(distinctUntilChanged()) 
    .subscribe(area => {
      this.themeService.updateTheme({primaryColor: area.color});
      sub.unsubscribe();
    })
  }

最好使用async 管道。

我相信这可以解决您的问题。

【讨论】:

  • 是的,没错,每次我进入屏幕时都会创建另一个订阅。泰
猜你喜欢
  • 1970-01-01
  • 2017-08-10
  • 2017-03-26
  • 2020-10-28
  • 2017-08-24
  • 1970-01-01
  • 1970-01-01
  • 2017-12-17
  • 2021-05-10
相关资源
最近更新 更多