【问题标题】:Angular 2 / Rxjs : do I really need to unsubscribe?Angular 2 / Rxjs:我真的需要退订吗?
【发布时间】:2017-07-30 09:02:48
【问题描述】:

我明白,当组件被销毁时,我必须取消订阅某些 Observable(即:具有 infinite 值的 Observable),以防止内存泄漏。我不需要为 finite Observables 这样做,因为它们会自动完成并自动 unsubscribe

但是如果我在我的组件中创建一个infinite Observable(例如FormGroup.valueChanges,或QueryList.changes),这个会被包含它的组件一起销毁,所以我 认为即使我退订,它们也不会发生内存泄漏。

这是一个简单的例子:

@Component({})
export class DummyComponent {
    form: FormGroup;

    constructor(private fb: FormBuilder) {
        this.form = this.fb.group({
            firstName: [''],
            lastName: ['']
        });
        this.form.valueChanges.subscribe(
            x => console.log(x)
        );
    }
}

这里,我不是来自this.form.valueChangesunsubscribe;当我的组件被销毁时,this.form.valueChanges 也会被销毁。

这种情况会不会出现内存泄漏?

【问题讨论】:

  • 你有没有尝试给 subscribe(...) 添加一个完整的回调,并检查它是否在组件被销毁时被调用?
  • 我做了,它没有被调用(我只用this.form.valueChanges做了测试)。
  • 我想这样会更好,但没有必要取消订阅。我不希望出现内存泄漏,因为当组件被销毁时,它会被垃圾收集,并且你的订阅也会随之而来。如果您在组件之外订阅或传递订阅(例如服务),那么这可能会阻止组件被 GC,但如果所有组件都在组件内,它应该不会受到伤害。

标签: angular memory-leaks rxjs


【解决方案1】:

正如 Babar 所提到的,您需要取消订阅以停止这些订阅以继续关注更改。

对于你的具体情况,我认为你有一个观点。

当我在同一个组件中有很多订阅时,我会做以下事情。

首先我创建“订阅”,一个订阅类型的空数组。

private subscriptions: Subscription[] = [];

然后每次我需要订阅时,我都会将其推送到数组中

this.subscriptions.push(this.form.valueChanges.subscribe(x => console.log(x)));

在 ngOnDestroy 中,我取消订阅数组中的每个订阅。

ngOnDestroy(): void {
  this.subscriptions.forEach((elem) => { elem.unsubscribe(); })
}

【讨论】:

  • 您可以使用 subscription.add() 方法相互添加订阅。那么你只需要退订top订阅即可。
【解决方案2】:

当你的组件被销毁时,你的订阅者不是还在等待任何事件发生,这也会消耗内存,有时它也可能会扰乱你的逻辑。例如路由器事件订阅,它将在您的应用程序中的任何地方触发并执行您在订阅中执行的代码。

第二种情况,如果您在组件之间切换并且从未取消订阅,您的应用将在一段时间后挂起,因为每当您加载组件时,新订阅者都会绑定。

@Component({})
export class DummyComponent implements OnDestroy {
 form: FormGroup;
 subscription: Subscription; // from rxjs
 constructor(private fb: FormBuilder) {
    this.form = this.fb.group({
        firstName: [''],
        lastName: ['']
    });
    this.subscription = this.form.valueChanges.subscribe(
        x => console.log(x)
    );
 }

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-31
    • 1970-01-01
    • 2017-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-13
    相关资源
    最近更新 更多