取消订阅 Rxjs Observables
Posted
技术标签:
【中文标题】取消订阅 Rxjs Observables【英文标题】:Unsubscribing to Rxjs Observables 【发布时间】:2020-10-28 09:07:33 【问题描述】:我开始使用一个使用 Rxjs observables 的遗留 angular 6 应用程序。组件中的可观察对象似乎没有使用我所看到的取消订阅。 ngOnInit 中的订阅示例:
this.service.getCustomerDetail(customers).subscribe(
(data) =>
this.customerData = data;
,
() =>
this.notify.addNotification(
new notification(
`Error retrieving customer data`
)
);
);
订阅者正在使用完成,即使其中没有任何内容,即 Rxjs 订阅的 Next、Error、Complete 值,但在我看来,它需要将这些推送到订阅中,然后在 ngOnDestroy 上取消订阅所有这些。即使完整在可观察对象内,这些没有取消订阅的订阅也会留在堆内存中,也就是导致内存泄漏,这是正确的吗?
在我的订阅使用错误和完整部分的情况下,我是否会使用 TakeUntil 方法,例如:
this.service.getCustomerDetail(customers)
.pipe(takeUntil(this.ngUnsubscribe))
.subscribe(
(data) =>
this.customerData = data;
,
() =>
//error section
this.notify.addNotification(
new notification(
`Error retrieving customer data`
)
);
,
() =>
//complete section
this.loadAddlDetail();
);
感谢您提供这方面的任何信息。
【问题讨论】:
takeUntil 方法是首选的角度解决方案***.com/questions/38008334/… @AdrianBrand 在描述中添加了一个问题,例如如果我已经有一个错误并完成订阅部分,我会使用 takeUntil 吗? 【参考方案1】:您可以使用 ngOnDestroy() 并在其中添加 unsubscribe(),如下所示
ngOnDestroy()
if(serviceSubscription != null)
serviceSubscription.unsubscribe();
或者您可以在 html 模板本身上使用异步管道,这样您就不必像下面那样手动取消订阅。
<p> observable | async </p>
【讨论】:
如果您的问题得到解决,请接受答案。谢谢 因此,例如,订阅点击了一个 http get,并将该数据加载到一个持久化和使用的对象数组中。在未添加取消订阅的情况下会发生什么情况是回调在堆上一直作为分配的内存直到它被销毁? 我也在考虑使用 TakeUntil,但是当它在 Next 中返回时没有服务 http 调用我将它设置为一个对象数组然后我有错误和完整的订阅区域.如果没有错误是混淆的地方,是否不会自动调用完整的。例如,如果我在 ngOnDestroy 上添加 TakeUntil,它也会调用 complete 和 next。【参考方案2】:有两种方法可以做到这一点。如果这是一个孤立的案例,以下就足够了
方法 1 - 如果这是一个孤立的案例
------------------------------------------ --------
课堂上
更改类声明以包含OnDestroy
export class AppComponent implements OnInit, OnDestroy
添加私有变量来存储订阅
private serviceSubscription = null
在 ngOnInit 中
this.serviceSubscription = this.service.getCustomerDetail(customers).subscribe(
(data) =>
this.customerData = data;
,
() =>
this.notify.addNotification(
new notification(
`Error retrieving customer data`
)
);
);
实施 OnDestroy
ngOnDestroy()
if (this.serviceSubscription != null)
this.serviceSubscription.unsubscribe()
------------------------------------------ --------------
方法 2 - 如果在多个地方看到这种情况
------------------------------------------ --------------
为组件component-base.ts
创建基类
import Subscription from 'rxjs';
import OnDestroy from '@angular/core';
export class ComponentBase implements OnDestroy
private subscriptions: Subscription[] = [];
protected rxs(s: Subscription): void
this.subscriptions.push(s);
ngOnDestroy()
this.subscriptions.forEach(x => x.unsubscribe());
从ComponentBase
扩展组件
export class AppComponent extends ComponentBase implements OnInit
在 ngOnInit 中
ngOnInit()
this.rxs(this.service.getCustomerDetail(customers).subscribe(
(data) =>
this.customerData = data;
,
() =>
this.notify.addNotification(
new notification(
`Error retrieving customer data`
)
);
));
【讨论】:
非常感谢,感谢您的反馈和示例。 Angular 的标准方法是使用 takeUntil 和单个主题来完成所有可观察对象或使用异步管道。订阅数组不是一个好的解决方案。 谢谢阿德里安,我正在调查 @AdrianBrand 如果我的订阅在第 3 部分已经有一个完整的部分,也就是我有一个获取数据的下一个部分,错误然后是一个调用其他一些方法的完整部分。在这种情况下,我应该使用将在 ngOnDestroy 上调用 .next 和 .complete 的 TakeUntil 吗?以上是关于取消订阅 Rxjs Observables的主要内容,如果未能解决你的问题,请参考以下文章