如何取消订阅应用程序中的所有订阅?

时间:2020-08-13 12:51:13

标签: angular rxjs

我有一个很大的应用程序,其中有很多订阅方法。如果我想退订其中之一,那么我将使用以下代码:

getUsersSubscription: Subscription;

ngOnInit() : void {

   this.getUsersSubscription = this.userService().subscribe(users => {
     ...something
   })
}

ngOnDestroy() : void {
   this.getUsersSubscription.unsubscribe();
}

问题是我的页面很多-组件也很多。我有jwt令牌,当它到期时,我正在注销用户。问题是当我这样做时,仍然有一些呼叫...注销后如何退订应用程序中的所有内容,因此我不需要通过页面中的所有组件对所有订阅重复此步骤?

我还使用拦截器来捕获jwt到期,并将用户重定向到登录页面。但是,如果用户单击某些内容(退出用户数秒之前),仍然会在登录页面上进行呼叫< / p>

2 个答案:

答案 0 :(得分:0)

如果您需要退订很多Observable,则应使用Subscription数组:

private subscriptions: Subscription[] = [];

ngOnInit() {
    this.subscriptions.push(this.userService.subscribe(users => {
     ...something
   }));
}

ngOnDestroy() {
    this.subscriptions.forEach(subscription => subscription.unsubscribe());
}

但是我认为您真正的问题是您可能有太多需要的订阅方式。

首先,应尽可能使用async管道。它可以很好地处理订阅和取消订阅,并且完全免费。

此外,请注意,通常不需要取消订阅冷的可观察变量(如HttpClient返回的可观察变量),因为当完成http请求时,可观察变量将终止。 您只需要取消订阅具有副作用的冷可观察物即可。

答案 1 :(得分:0)

与上一个选项不同,您最好遵循以下路线:

您可以使用takeUntil() operator,一旦发生给定事件,它将自动为您取消订阅。 例如:

在某些组件中

...

myObservable$ = this.service.foo().pipe(
  takeUntil(this.loginService._loggedOutEmitter) <-- (0)
).subscribe()

...

在loginService中

...

_loggedOutEmitter = new Subject<boolean>(); <---- (1)

loggedOut() {
  *some logout logic *
  this._loggedOutEmitter.next(true); <----------- (2)
}

...

就像在其他解决方案中一样,您将必须导入特定的服务,并且需要为每个Observable(0)添加特定的行,但是这种方式在内存方面应该稍微友好一些,因为您不需要跟踪您的订阅。 相反,您只有一个Observable(1),它发出一次(2)。

我仍然觉得您的提议方式(清除OnDestroy [顺便说一句,我认为也可以使用takeUntil()方法完成)]