取消订阅来自不同功能的多个订阅

Unsubscribing Multiple Subscription from Different Functions

我有多个订阅功能。首先我把它放在 ngOnInit() 上,然后我有另一个函数叫做 onSelectVillain()。所以我的问题是您可以只使用 this.subscription.unsubscribe()。或者我应该声明另一个订阅?

subscription: Subscription;

    ngOnInit() {
      this.subscription = this.heroService.getHeroes()
                       .subscribe(
                         heroes => this.heroes = heroes,
                         error =>  this.errorMessage = <any>error);
    }

    onSelectVillain(event) {
      this.subscription = this.villainService.getVillains()
                       .subscribe(
                         .....
    }

    ngOnDestroy(){
     this.subscription.unsubscribe()
    }

使用单独的订阅会更干净 - 如果您使用相同的字段,您将永远不会(手动)取消订阅第一个订阅。此外,如果您不想让您的组件与大量字段混在一起,那么只保留订阅引用我建议使用一种模式,该模式涉及仅使用一个主题,该主题在 ngOnDestroy 触发,并且在每次订阅之前您将使用 takeUntil。 所以您的代码可能如下所示:

private ngUnsubscribe = new Subject();

ngOnInit() {
  this.heroService.getHeroes()
                  .takeUntil(this.ngUnsubscribe)
                  .subscribe(
                     heroes => this.heroes = heroes,
                     error =>  this.errorMessage = <any>error);
}

onSelectVillain(event) {
  this.villainService.getVillains()
                     .takeUntil(this.ngUnsubscribe)
                     .subscribe(
                     .....
}

ngOnDestroy(){
    this.ngUnsubscribe.next();
    this.ngUnsubscribe.complete();
}

请参阅 this 以获取更多参考。

请注意,订阅是 "finite",因此在调用完整状态的情况下,不一定需要手动取消订阅。 This 可能是一个很好的参考点。

一旦 subscription 值被替换,之前的订阅将丢失,它与任何其他值没有区别。

更简洁的方法是使用具有有意义名称的不同订阅 - heroesSubscriptionvillainsSubscription 等:

heroesSubscription: Subscription;
villainsSubscription: Subscription;

ngOnInit() {
  this.heroesSubscription = this.heroService.getHeroes().subscribe(...);
}

onSelectVillain(event) {
  // possibly needs to unsubscribe previous subscription
  if (this.villainsSubscription)
    this.villainsSubscription.unsubscribe()

  this.villainsSubscription = this.villainService.getVillains().subscribe(...)
}

ngOnDestroy(){
 this.heroesSubscription.unsubscribe()
 this.villainsSubscription.unsubscribe()
}

如果onSelectVillain可能被多次调用,之前的订阅应该退订。

该代码没有显示手动订阅的好处。当仅在视图中使用可观察值时,可以使用 async 管道代替,因为它会自动完成所有 subscription/unsubscription 工作:

{{ heroService.getHeroes() | async }}