如何正确退订这种可观察的内容

时间:2018-11-02 06:38:44

标签: angular typescript rxjs

我有一个getDimensions方法,该方法返回一个Observable<string[]>

dimension.service.ts

public getDimensions(id: string): Observable<string[]> {
    return this.service.loadDimensions(id);
}

reloader.service.ts

public update(idsToUpdate: string[]): void {

    idsToUpdate.map(id => this.dimensionService.getDimensions(id)).pipe(
        map(
             newDimensions => this.updateDimensions(newDimensions)
        )
    ).subscribe(); // ToDo: unsubscribe

}

然后在应用程序的另一部分,我在update方法中调用此方法。问题是,我不知道如何正确退订getDimensions。一种可能的解决方案是创建一个Subscription,然后在OnDestroy中调用unsubscribe,但是对我来说,这不是一个好的解决方案:

  • 这是我在整个应用程序中使用的服务,因此OnDestroy钩子永远不会发生
  • 我每update秒调用一次n方法,因此每n秒就会有一个新的订阅

可能的解决方案: (不好)

reloader.service.ts

private subscriptions: Subscription = new Subscription();

...
...

public update(idsToUpdate: string[]): void {

    const sub = idsToUpdate.map(id => this.dimensionService.getDimensions(id)).pipe(
        map(
             newDimensions => this.updateDimensions(newDimensions)
        )
    ).subscribe(); // ToDo: unsubscribe

    this.subscription.add(sub);

}

...
...

public onDestroy(): void {
    this.subscription.unsubscribe();
}

编辑:

正如@jgerstle在他的评论中提到的那样,如果可观察对象完成(这是我的情况),则无需退订。

2 个答案:

答案 0 :(得分:0)

如果您希望在数据或可观察到的数据完整时退订

public update(idsToUpdate: string[]): void {

    const sub = idsToUpdate.map(id => this.dimensionService.getDimensions(id)).pipe(
        map(
             newDimensions => this.updateDimensions(newDimensions)
        )
    ).subscribe(() => sub.unsubscribe() ); // or you can use complate 

}

答案 1 :(得分:0)

订阅的添加功能可能无法执行您想要的操作。 在文档中指出以下内容。

   /**
     * Adds a tear down to be called during the unsubscribe() of this
     * Subscription.
     *
     * If the tear down being added is a subscription that is already
     * unsubscribed, is the same reference `add` is being called on, or is
     * `Subscription.EMPTY`, it will not be added.
     *
     * If this subscription is already in an `closed` state, the passed
     * tear down logic will be executed immediately.
     *
     * @param {TeardownLogic} teardown The additional logic to execute on
     * teardown.
     * @return {Subscription} Returns the Subscription used or created to be
     * added to the inner subscriptions list. This Subscription can be used with
     * `remove()` to remove the passed teardown logic from the inner subscriptions
     * list.
     */
    add(teardown: TeardownLogic): Subscription;

我猜您想取消订阅idsToUpdate。您可以像平常一样保留订阅的引用,然后执行sub.unsubscribe()

以下是修改代码的示例

private sub: Subscription;

...
...

public update(idsToUpdate: string[]): void {

    this.sub = idsToUpdate.map(id => this.dimensionService.getDimensions(id)).pipe(
        map(
             newDimensions => this.updateDimensions(newDimensions)
        )
    ).subscribe(); // ToDo: unsubscribe

}

...
...

public onDestroy(): void {
    if(this.sub) this.sub.unsubscribe();

}