← Angular コース
21. Observable と RxJS — 時間とともに届く値
前のレッスンの HttpClient は、結果を Observable という入れ物で返します。Observable は「これから(非同期に)届くかもしれない値の流れ」を表すもので、subscribe(購読)して初めて処理が動き、値が届くとコールバックが呼ばれます。1回きりの通信結果も、何度も発火するイベントも、同じ Observable として扱えるのが特徴です。
RxJS は、その Observable を加工するための演算子(オペレータ)を集めたライブラリです。pipe() の中に map(値を変換)や filter(条件で絞る)などを並べると、届いた値を流れの中で次々に加工できます。Angular の通信やフォームの値の監視など、非同期の処理の多くがこの仕組みの上に成り立っています。
つまずきやすいのは、subscribe しっぱなしにすると購読が残り続け、メモリリークの原因になることです。テンプレートでは async パイプ({{ data$ | async }})を使うと、購読と解除をフレームワークが自動でやってくれるため安全で簡潔です。手動で subscribe したときは、ngOnDestroy での解除や takeUntilDestroyed() を忘れないようにします。
サンプルコード(フレームワーク環境が必要なため表示のみ)
import { Component, inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { map } from 'rxjs';
import { AsyncPipe } from '@angular/common';
type User = { id: number; name: string };
@Component({
selector: 'app-user-names',
imports: [AsyncPipe],
// async パイプが購読と解除を自動で行う
template: '@for (name of names$ | async; track name) { <p>{{ name }}</p> }',
})
export class UserNamesComponent {
private http = inject(HttpClient);
// pipe + map で「Userの配列」を「名前の配列」に変換する流れを作る
names$ = this.http
.get<User[]>('/api/users')
.pipe(map((users) => users.map((u) => u.name)));
}