リアクティブプログラミングとは?

リアクティブプログラミングは、データストリームと変更の伝播に焦点を当てたプログラミングパラダイムです。データを明示的に取得して段階的に処理するコードを書く代わりに、データがどのように流れて時間とともに変換されるべきかを記述します。値が変わると、更新は自動的にアプリケーション全体に伝播します。スプレッドシートのように考えてください。セルA1を更新すると、A1を参照するすべてのセルが自動的に再計算されます。このアプローチは、ユーザーインタラクション、HTTP応答、WebSocketメッセージ、タイマーなどの非同期イベントの処理に優れています。

RxJSはどのように機能しますか?

RxJS(Reactive Extensions for JavaScript)は、Observablesを通じてリアクティブプログラミングを実装します。Observablesは時間とともに値を発行するオブジェクトです。コアコンセプトは以下の通りです:

  1. Observable: 値を発行するデータソース(クリックイベントのストリームやAPI応答など)
  2. Observer: 発行された値にコールバック(next、error、complete)を通じて反応するコンシューマー
  3. Subscription: ObservableとObserverの間の接続
  4. Operators: データストリームを変換、フィルタリング、結合、または操作する関数
  5. Subjects: データソースとコンシューマーの両方として機能する特別なObservables。マルチキャスティングを可能にします

pipe()メソッドでoperatorをチェーンしてデータパイプラインを作成し、生のストリームをアプリケーションが必要とするデータ形状に変換します。

ツール説明

RxJS Playgroundは、RxJSリアクティブプログラミングコンセプトを実験するためのインタラクティブなブラウザベースのサンドボックスです。エディターでRxJSコードを直接書いて実行でき、RxJSライブラリとすべてのoperatorに完全にアクセスできます。Playgroundはタイピング時に自動的にコードを実行し(debouncing付き)、ターミナルスタイルのパネルにコンソール出力を表示します。開発環境をセットアップすることなく、RxJSコンセプトの学習、データ変換のプロトタイピング、Observableパイプラインのデバッグ、operatorの組み合わせのテストに最適です。

機能

  • RxJSライブラリへの完全アクセス: すべての作成関数(offromintervalfromEventなど)とoperatorが利用可能
  • リアルタイム実行: タイピング時に500msのdebounceで自動的にコードが実行される
  • ターミナル出力: コンソールログ、エラー、警告がスタイル付きターミナルに表示される
  • シンタックスハイライト: 適切なシンタックスハイライト付きJavaScriptコードエディター
  • 戻り値表示: 最終的な式の値が矢印記号で自動的にログされる
  • エラーハンドリング: シンタックスおよびランタイムエラーの明確なエラーメッセージ
  • Operatorsモジュール: パイプベースの変換のためのrxjs/operatorsへの直接アクセス

基本的なObservable作成:

const { of, from, interval } = rxjs;

// 個別の値を発行
of(1, 2, 3).subscribe((x) => console.log(x));

// 配列をObservableに変換
from([10, 20, 30]).subscribe((x) => console.log(x));

Operatorの使用:

const { of } = rxjs;
const { map, filter, take } = operators;

of(1, 2, 3, 4, 5)
  .pipe(
    filter((x) => x % 2 === 0),
    map((x) => x * 10),
  )
  .subscribe((x) => console.log(x));
// 出力: 20, 40

ストリームの結合:

const { of, merge, concat } = rxjs;

const stream1 = of("A", "B");
const stream2 = of("X", "Y");

merge(stream1, stream2).subscribe((x) => console.log("merge:", x));
concat(stream1, stream2).subscribe((x) => console.log("concat:", x));

マルチキャスティング用Subjects:

const { Subject, BehaviorSubject } = rxjs;

const subject = new Subject();
subject.subscribe((v) => console.log("Observer 1:", v));
subject.subscribe((v) => console.log("Observer 2:", v));
subject.next(1);
subject.next(2);

変換パイプライン:

const { from } = rxjs;
const { map, reduce, toArray } = operators;

from([1, 2, 3, 4, 5])
  .pipe(
    map((x) => x * 2),
    toArray(),
  )
  .subscribe((arr) => console.log("Doubled:", arr));

利用可能なモジュール

rxjs(メインモジュール):

  • 作成: offromintervaltimerrangegeneratedeferiif
  • 結合: mergeconcatcombineLatestforkJoinziprace
  • Subjects: SubjectBehaviorSubjectReplaySubjectAsyncSubject
  • ユーティリティ: firstValueFromlastValueFromisObservable

operators(パイプ可能なoperator):

  • 変換: mappluckscanreducebufferswitchMapmergeMapconcatMap
  • フィルタリング: filtertaketakeUntilskipdebounceTimethrottleTimedistinctUntilChanged
  • 結合: withLatestFromcombineLatestWithmergeWithstartWith
  • エラーハンドリング: catchErrorretryretryWhen
  • ユーティリティ: tapdelaytimeouttoArrayshareshareReplay

ユースケース

  • RxJSの学習: 実践的な実験を通じてObservableコンセプトを理解する
  • データフローのプロトタイピング: 実装前にリアクティブデータパイプラインを設計およびテストする
  • Operatorのデバッグ: 簡略化された例でoperatorの動作を分離して検証する
  • 面接対策: リアクティブプログラミングパターンと一般的な問題を練習する
  • 教育デモンストレーション: ライブでインタラクティブな例を使用してリアクティブコンセプトを示す