Angular. Когда не надо отписываться в RxJS?

Всегда надо отписываться

Если использовать async pipe, то за вас отпишется Angular. Во всех остальных случаях лучше отписываться самостоятельно.

Допускается не отписываться в потоках, где будет гарантировано вызван complete такие как of, timer или http запрос.

В общем случае (http в частности) верно утверждение: если Observable выполняется дольше, чем живёт его подписка, то отписываться нужно, иначе можно не отписываться. Другими словами, если время http запрос выполнится после destroy компонента, то отписываться надо.

На сегодняшний день наиболее популярны 2 декларативных подхода отписки:

takeUntil

Паттерн takeUntil() от члена RxJs core team - Nicholas Jamieson

import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';

@Component({
  selector: 'app-inbox',
  templateUrl: './inbox.component.html',
})
export class InboxComponent implements OnInit, OnDestroy {
  this.destroy$ = new Subject<void>();

  ngOnInit() {
    interval(1000)
      .pipe(takeUntil(this.destroy$))
      .subscribe(val => console.log(val));
  }

  ngOnDestroy() {
    this.destroy$.next();
    this.destroy$.complete();
  }
}

takeUntil() должен быть последним оператором внутри pipe.

untilDestroyed

Подход от Netanel Basal. Является развитием способа takeUntil: не требует создания Subject и вызова у него методов next и complete.

import { untilDestroyed } from 'ngx-take-until-destroy';

@Component({
  selector: 'app-inbox',
  templateUrl: './inbox.component.html',
})
export class InboxComponent implements OnInit, OnDestroy {
  ngOnInit() {
    interval(1000)
      .pipe(untilDestroyed(this))
      .subscribe(val => console.log(val));
  }

  // Хук всегда должен присутствовать в компоненте, даже если пустой
  ngOnDestroy() { }
}

Похожие записи

Поисковый запрос с помощью RxJS

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