首页 > 解决方案 > 如果我重新分配一个存储 rxjs 订阅的变量,那会取消订阅吗?

问题描述

这是我在 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变量吗?我的假设是前者是正确的。所以如果你有答案,也能得到它背后的解释可能会很好。

标签: angularrxjs

解决方案


切换到新的 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();
}

推荐阅读