Angular 2 / Rxjs:我真的需要取消订阅吗?

时间:2017-03-09 11:32:47

标签: angular memory-leaks rxjs

我知道在销毁组件时我必须取消订阅某些Observable(即:具有无限值的Observable),以防止内存泄漏。对于有限 Observable,我不需要这样做,因为它们将自动完成unsubscribe

但是如果我在我的组件中创建无限 Observable(例如FormGroup.valueChangesQueryList.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)
        );
    }
}

在此,我unsubscribe并非this.form.valueChanges;当我的组件被销毁时,this.form.valueChanges也将被销毁。

在这种情况下是否会出现内存泄漏?

2 个答案:

答案 0 :(得分:8)

正如Babar所提到的,您需要取消订阅才能阻止这些订阅继续观看更改。

对于您的特定情况,我认为您有一点意见。

当我在同一组件中有大量订阅时,我做的一件事如下。

首先,我创建" subscriptions",一个空的Subscription类型数组。

private subscriptions: Subscription[] = [];

然后每当我需要订阅时,我将其推入数组

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

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

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

答案 1 :(得分:3)

当您的组件被销毁时,您的订阅者不会等待任何事件发生在他们身上,它会耗费内存,有时也可能会打扰您的逻辑。例如,路由器事件订阅它将在您的应用程序中的任何位置触发,并执行您在订阅中执行的代码。

我是第二种情况,如果您在组件之间切换并且从未取消订阅,您的应用程序会在一堆时间后挂断,因为无论何时加载组件,新订阅者都会绑定。

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<ul class="in-page-menu in-page-menu--vertical" id="sticky">
  <li>
    <a class="sticky-menu-link" href="#change-content">Change your content web easily</a>
  </li>
  <li>
    <a class="sticky-menu-link" href="#manage-order">Manage your order</a>
  </li>
  <li>
    <a class="sticky-menu-link" href="#inventory">Inventory management</a>
  </li>
  <li>
    <a class="sticky-menu-link" href="#manage-relationship">Manage your relationship</a>
  </li>
  <li>
    <a class="sticky-menu-link" href="#bcommerce">B2B commerce</a>
  </li>
  <li></li>
</ul>