![](/img/trans.png)
[英]Angular/RxJS When should I unsubscribe from `Subscription`
[英]If I reassign a variable which stores an rxjs subscription, does that unsubscribe?
这是我在 Angular 中的代码原型:
import { Subscription } from 'rxjs';
import { SomeClass, SomeOtherClass } from './my-component.model.ts';
import { OnDestroy } from '@angular/core';
@Component({
selector: 'app-my-component',
templateUrl: './my-component.component.html',
styleUrls: ['./my-component.component.scss'],
})
export class AnalysisToolsComponent implements OnDestroy {
private sub: Subscription;
// instance of some class I defined in my models which has an event emitter
instance = new SomeClass();
// this function might get called more than once
someFunction() {
sub = this.instance.onEvent.subscribe( () => {})
}
// some other function which results in a reassignment of instance to maybe some other class
someOtherFunction() {
instance = new SomeOtherClass();
}
ngOnDestroy() {
if (this.sub) {
this.sub.unsubscribe();
}
}
}
有人可能会问为什么我要重新分配 sub。 这基本上是因为我有一个子组件,它是一个工具栏,一次只能选择一个工具。 所以我一次只需要一个 sub 来监听与工具栏交互的事件。
每次切换工具时我都应该取消订阅吗? 或者我可以重新分配sub
变量吗? 我的假设是前者是正确的。 因此,如果您有答案,也可以得到其背后的解释。
最好使用switchMap
切换到新的 Observable 并自动取消订阅旧的switchMap
。 要在组件被销毁时取消订阅 Observable,请使用 takeUntil-destroy 模式。
tool$ = new BehaviorSubject<SomeTool>(new SomeTool());
private destroy$ = new Subject();
ngOnInit() {
this.tool$.pipe(
// use switchMap to map to a new onEvent Observable and unsubscribe from the old one
switchMap(tool => tool.onEvent),
// use takeUntil pattern to unsubscribe from tool$ when the component gets destroyed
takeUntil(this.destroy$)
).subscribe( () => {} )
}
switchTool() {
// supply a new Observable or Object containing an Observable to your Subject
this.tool$.next(new SomeOtherTool()); // presuming SomeOtherTool extends SomeTool
}
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
您可以取消订阅如下内容,
private sub: Subscription[] = [];
...
this.sub.push(this.instance.onEvent.subscribe( () => {}));
...
ngOnDestroy() {
// prevent memory leak when component destroyed
this.subscriptions.forEach(s => s.unsubscribe());
}
我可以重新分配子变量吗?
这种方法不需要
它将unsubscribe()
subscriptions
持有的所有Subscription
。
所有这些 observable 都是在组件中创建的吗? 如果是这样,那么当组件被销毁时,所有属性都会随之进入垃圾收集。 您会从订阅到 observable 的内存泄漏,这些 observable 不是在组件被销毁的同时被垃圾收集的。
如果您的组件实例化了一个 observable 并且没有其他任何东西持有对该 observable 的引用,那么取消订阅是不必要的,因为 observable 会与组件一起进入垃圾收集。
如果您的组件仍然被订阅并且组件不能被垃圾收集,因为订阅在服务中的 observable 上仍然处于活动状态,那么在服务中仍然具有活动引用的 observable 将导致内存泄漏。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.