🗒️

【Angular】RxJS: first() や takeUntil() を使うべき。 処理が走り続ける危険と端末発熱について

に公開

Angular + RxJSの開発で、Observableのsubscribeを行う場面がよくあり、そのまま使うと予期せぬバグやパフォーマンス低下の原因になることがある。


☠️危険パターン
 
以下のような問題が起きる。
・subscribe()をそのまま使うと、Observableが完了しない限り、購読(監視)はずっと続き、データが来るたびに処理が走る。
・画面遷移してコンポーネントが破棄されても、購読が生きていると処理が続き、端末のメモリやバッテリーを消費して端末が熱くなる。

//component.ts
this.userData$.subscribe(user => {
  // ユーザー情報の処理
  console.log(user);
});

✅ 解決方法①:first()で一度だけ値を受け取る
 ・first() は、最初の値だけを受け取ると 自動で購読を解除(初期表示など)

//component.ts
import { first } from 'rxjs/operators';

this.userData$.pipe(
  first()
).subscribe(user => {
  console.log(user);
});

✅ 解決方法②:takeUntil()で明示的に購読を終了させる

  • takeUntil()は、コンポーネント破棄を検知して購読を自動で解除できる。
//component.ts
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';

private onDestroy$ = new Subject<void>();

this.userData$.pipe(
  takeUntil(this.onDestroy$)
).subscribe(user => {
  console.log(user);
});

// コンポーネント破棄時に発火して、Observableを中断する。
ngOnDestroy(): void {
  this.onDestroy$.next();
  this.onDestroy$.complete();
}

Discussion