如何取消订阅角度组件中的多个可观察对象?

Ren*_*tos 11 observable rxjs angular

取消订阅多个 observable的最佳策略是什么?为了清楚起见,当应用程序不大并且不需要诸如ngrx 之类的解决方案时,我会使用这种方法,因为在这种情况下会过度设计

目前我使用订阅实例来添加所有订阅,然后当组件被销毁时我调用取消订阅方法。但我也看到了使用rxjs 中takeUntil 的替代方案。

export class MyComponent implements OnInit, OnDestroy {

  $firstObservable: Observable<number> = timer(0, 1000);
  $secondObservable: Observable<number> = timer(0, 1000);

  private _subscriptions = new Subscription();

  constructor() { }

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

  ngOnInit(): void {
    this._subscriptions .add(
      this.$firstObservable.subscribe(console.log));

    this._subscriptions .add(
      this.$secondObservable.subscribe(console.log));
  }

}
Run Code Online (Sandbox Code Playgroud)

最好的解决方案是什么?

Har*_*maz 9

我建议您使用可takeUntil()管道操作符:https ://www.learnrxjs.io/operators/filtering/takeuntil.html

通过这种方式,您可以创建一个Subject,用于ngOnDestroy一次性发出值和取消订阅多个订阅

 unsubscribeSignal: Subject<void> = new Subject();

 $firstObservable: Observable<number> = timer(0, 1000);
 $secondObservable: Observable<number> = timer(0, 1000);

 ngOnInit() {

    this.$firstObservable
    .pipe(
       takeUntil(this.unsubscribeSignal.asObservable()),
    )
    .subscribe(result => {});

    this.$secondObservable
    .pipe(
       takeUntil(this.unsubscribeSignal.asObservable()),
    )
    .subscribe(result => {});

  }

  ngOnDestroy(){
    this.unsubscribeSignal.next();
    // Don't forget to unsubscribe from subject itself
    this.unsubscribeSignal.unsubscribe();
  }
Run Code Online (Sandbox Code Playgroud)


Aam*_*zad 6

Subscribe类有一个add方法可以将多个订阅添加到一个订阅中,然后可以unsubscribed一次性添加。

subscription1 = observable.subscribe(
    // next, err, complete etc
);

subscription2 = observable.subscribe(
    // next, err, complete etc
);
Run Code Online (Sandbox Code Playgroud)

添加多个订阅

subscription1.add(subscription2);
Run Code Online (Sandbox Code Playgroud)

立即取消所有订阅。

subscription1.unsubscribe();
Run Code Online (Sandbox Code Playgroud)


小智 5

我很失望人们甚至没有提到async管道。

它非常强大,让您无需担心订阅和使用推送检测策略。

要使用它,只需从您的 TS 中删除订阅,并将值分配给您的变量,这些变量将被键入为 observable。

就看代码的精简和简洁(不知道是不是一个词,但有点不在意)

export class MyComponent {
  firstObservable$: Observable<number> = timer(0, 1000);
  secondObservable$: Observable<number> = timer(0, 1000);

  combination$ = combineLatest(this.firstObservable$, this.secondObservable$)
    .pipe(tap(() => console.log()));
}
Run Code Online (Sandbox Code Playgroud)

在你的 HTML

<ng-container *ngIf="combination$ | async">
  Observables are being observed.
</ng-container>
Run Code Online (Sandbox Code Playgroud)

(尽管它不适合您的问题示例,但您已经可以看到它的方式更简洁更简单)

最好的部分是,您不必再担心内存泄漏。Angular 负责所有的订阅,让你只关心你的代码(这是一个好的框架应该做的)。