取消订阅订阅数组

时间:2017-07-13 17:23:10

标签: angular typescript rxjs

在一个Angular应用程序中,我通过将所有订阅推送到一个数组中来管理我的订阅,然后循环遍历它并在ngOnDestroy期间取消订阅。

private subscriptions: Subscription[] = []
this.subscriptions.push(someObservable.subscribe(foo => bar))

我的问题是我没有找到足够干净的方法来处理取消订阅。理想的方式是简单的

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

但这不起作用。值得注意的是,我在注销后仍然收到Firebase权限错误(“工作”方法不会发生这种情况)。有趣的是,如果我把它拉到一个单独的类中,完全相同的方法可以

export class Utils {
    public static unsubscribeAll (subObject: {subscriptions: Subscription[]}) {
        subObject.subscriptions.forEach(subscription => subscription.unsubscribe())
    }
}

// ---------- back to the component

ngOnDestroy () {
    Utils.unsubscribeAll({subscriptions: this.subscriptions}) // no Firebase errors
}

但我真的不喜欢这个解决方案,主要是因为它只在我将数组包装在一个对象中以便它作为引用传递时才有效。我发现的另一种工作方法是将其写为for循环:

ngOnDestroy () {
    /* tslint:disable */
    for (let i = 0; i < this.subscriptions.length; i++) {
        this.subscriptions[i].unsubscribe()
    }
    /* tslint:enable */
}

但是除了不必要的长度之外,它也让TSLint抱怨,因为它认为我应该使用for-of循环(这不起作用)所以我每次都要抛出额外的注释。

目前我正在使用Utils选项作为“最佳”解决方案,但我仍然不满意。是否有一种更清洁的方法可以做到这一点,我错过了?

2 个答案:

答案 0 :(得分:17)

由于没有人愿意将答案作为答案发布,我想我会这样做。

如果您仅使用数组对其进行分组以进行大规模取消订阅,则可以通过将它们合并到现有订阅中来完成相同的操作。对于我的设置,只需将空数组更改为空订阅,然后将push更改为add

private subscriptions = new Subscription()
this.subscriptions.add(someObservable.subscribe(foo => bar))

然后,当您想要取消订阅所有内容时,只需取消订阅容器订阅即可处理所有内容。

ngOnDestroy () {
    this.subscriptions.unsubscribe()
}

注意:您也可以在每个订阅上使用takeUntil,但我觉得这种方法更简单,对我正在做的事情更有意义。

答案 1 :(得分:0)

subs: Subscription[] = [];

ngOnInit(): void {
    this.subs.push(someObservable.subscribe(foo => bar));
}

ngOnDestroy(): void {
    this.subs.map(s => s.unsubscribe);
}