Как отписаться от нескольких наблюдаемых в угловой составляющей? - PullRequest
4 голосов
/ 29 марта 2019

Какова лучшая стратегия для отписки множественных наблюдаемых в угловых? Просто чтобы прояснить, я использую этот подход, когда приложение невелико и не нуждается в таких решениях, как ngrx , которые в этом случае были бы избыточным .

В настоящее время я использую экземпляр подписки, чтобы добавить все подписки, и после этого, когда компонент был уничтожен, я вызываю метод отказа от подписки. Но я также видел альтернативы, использующие takeUntil из rxjs .

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));
  }

}

Какое будет лучшее решение?

Ответы [ 4 ]

4 голосов
/ 29 марта 2019

Я очень разочарован, что люди даже не упоминают о async трубе.

Это очень мощный инструмент, позволяющий вам перестать беспокоиться о подписках и использовать стратегию обнаружения push.

Чтобы использовать его, просто удалите подписки из вашего TS и присвойте значения вашим переменным, которые будут напечатаны как наблюдаемые.

Достаточно взглянуть на сокращение кода и простоту (не знаю, слово ли это, но все равно)

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()));
}

В вашем HTML

<ng-container *ngIf="combination$ | async">
  Observables are being observed.
</ng-container>

(хотя он не подходит для вашего примера вопроса, вы уже можете видеть, как он чище и проще)

И что самое приятное, вам больше не нужно беспокоиться об утечках памяти. Angular заботится обо всех подписках, оставляя вас заботиться только о вашем коде (что и должно делать хорошая среда).

3 голосов
/ 29 марта 2019

Я предлагаю вам использовать takeUntil() pipeable оператор: 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();
  }
1 голос
/ 29 марта 2019

Самый простой способ - сохранить объект subscribtion, а ngDestory вызвать метод отказа от подписки.

export class MyComponent implements OnInit, OnDestroy {

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

  private _subscriptions :any[] = [];

  constructor() { }

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

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

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

   ngOnDestroy(){
    this._subscriptions.forEach(sub => sub.unsubscribe) ; // ?‍♂️?‍♂️
  }

}
0 голосов
/ 29 марта 2019

Я нашел этот пост, который ясно объясняет все о отписках.Это очень полезно.

Лучший способ отменить подписку RxJS Observables в угловых приложениях!

Благодаря Томас Траян

...