JavaScript、Angular、RxJSにおけるホットとコールドオブザーバブル:詳解と使い分け
JavaScript、Angular、RxJSにおけるホットとコールドオブザーバブル
JavaScript、Angular、RxJSにおいて、オブザーバブルはデータストリームを表現する重要な概念です。オブザーバブルには、ホットとコールドの2種類があり、それぞれ異なる動作と特性を持ちます。この解説では、ホットとコールドオブザーバブルの理解を深め、適切な場面での使い分けを支援するために、それぞれの詳細な説明と比較を提供します。
ホットオブザーバブル
ホットオブザーバブルは、時間経過とともに値を発行するストリームです。購読 (subscribe) する前にすでに値を発行しており、購読後に発行された値のみを受信できます。
- 購読の開始・終了に影響されない
- 購読後に発行された値のみを受信できる
- 複数の購読者が同じ値を受信する
- 購読前に値を発行する
- DOMイベントストリーム: クリック、マウスオーバーなど
- リアルタイムデータストリーム: 株価、センサーデータなど
- イベント発生ストリーム: ボタンクリック、マウス移動など
コールドオブザーバブル
コールドオブザーバブルは、購読時に初めて値を発行するストリームです。購読ごとに新しいストリームが作成され、購読者はそのストリームから発行された値のみを受信できます。
- 購読者ごとに個別のストリームを持つ
- 購読時に初めて値を発行する
- 数学関数ストリーム
- ネットワークリクエストストリーム
- ファイル読み込みストリーム
ホットとコールドオブザーバブルの比較
項目 | ホットオブザーバブル | コールドオブザーバブル |
---|---|---|
値発行タイミング | 購読前 | 購読時 |
ストリーム共有 | 複数購読者で共有 | 購読者ごとに個別のストリーム |
購読開始・終了の影響 | なし | 影響を受ける |
典型的な例 | イベントストリーム、リアルタイムデータストリーム | ファイル読み込みストリーム、ネットワークリクエストストリーム |
Angularでの利用
Angularでは、イベントバインディングや非同期処理などにオブザーバブルを幅広く利用しています。例えば、@Output
デコレータで装飾されたプロパティは、ホットオブザーバブルとして公開されます。一方、HttpClient
サービスを用いたHTTPリクエストは、コールドオブザーバブルとして扱われます。
RxJSオペレーター
RxJSには、ホットとコールドオブザーバブルの変換に役立つオペレーターが用意されています。例えば、fromEvent
オペレーターはDOMイベントをホットオブザーバブルに変換し、defer
オペレーターはコールドオブザーバブルの作成を遅延させます。
import { Observable, interval } from 'rxjs';
const hotObservable = interval(1000);
hotObservable.subscribe(value => console.log('Hot observable:', value));
setTimeout(() => {
hotObservable.subscribe(value => console.log('Late subscriber:', value));
}, 2000);
import { Observable, fromEvent } from 'rxjs';
const button = document.querySelector('button');
const coldObservable = fromEvent(button, 'click');
coldObservable.subscribe(event => console.log('Cold observable:', event));
この図では、時間軸上に値が流れるストリームを表しています。ホットオブザーバブルは、購読 (subscribe) 前にすでに値を発行しており、購読後に発行された値のみを受信できます。
アナロジー
ホットオブザーバブルとコールドオブザーバブルを、日常生活の例に例えると理解しやすくなります。
- コールドオブザーバブル
ボタンを押して起動するゲームはコールドオブザーバブルに例えられます。ゲームはボタンを押すまで起動せず、起動後にプレイした内容のみが記録されます。 - ホットオブザーバブル
テレビのニュース番組はホットオブザーバブルに例えられます。番組は常に放送されており、チャンネルを変えて視聴を開始した時点で、その時点から放送されているニュースを受信できます。
javascript angular rxjs