Zademy

Vanilla JavaScriptで学ぶRxJS基礎コース

RxJS; JavaScript; ReactiveProgramming
words 単語

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

リアクティブプログラミングは、時間とともに変化するデータの流れ(ストリーム)を扱う考え方です。

  • マウスクリックはイベント。
  • 入力欄の文字入力もイベント。
  • HTTPレスポンスは非同期イベント。

データが来たかを何度も確認するのではなく、届いた瞬間に反応します。

2. RxJSとは

RxJSは、Observableを使って非同期処理やイベント処理を組み立てるためのJavaScriptライブラリです。

インストール

npm:

npm install rxjs

CDN:

<script src="https://unpkg.com/rxjs@7/dist/bundles/rxjs.umd.min.js"></script>

Vanilla JSの基本構成

  • index.html
  • app.js
  • styles.css(任意)

3. Observable

Observableは、時間の経過とともに0件、1件、または複数の値を発行できるデータソースです。

const { of, from, interval } = rxjs;

of(1, 2, 3).subscribe(console.log); // 1, 2, 3
from(["A", "B"]).subscribe(console.log); // A, B

fromEvent

const { fromEvent } = rxjs;
const button = document.getElementById("btn");

const click$ = fromEvent(button, "click");
const sub = click$.subscribe(() => console.log("click"));

subscribe / unsubscribe

const { interval } = rxjs;

const sub = interval(1000).subscribe(v => console.log("tick", v));
setTimeout(() => sub.unsubscribe(), 5000);

4. 基本オペレーター

オペレーターは、Observableの値を変換・フィルタする関数です。

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

of(1, 2, 3, 4, 5)
	.pipe(
		filter(n => n % 2 === 1),
		map(n => n * 10),
		take(2)
	)
	.subscribe(console.log); // 10, 30

このコースで扱う主なオペレーター

  • 生成: of, from, interval, timer
  • 変換: map, filter
  • 結合: merge, concat
  • 抽出: take, first, debounceTime

5. DOMイベントの処理

クリックカウンター

const { fromEvent } = rxjs;

const btn = document.getElementById("btn");
const output = document.getElementById("output");
let count = 0;

fromEvent(btn, "click").subscribe(() => {
	count += 1;
	output.textContent = `Clicks: ${count}`;
});

ライブ検索(基本)

const { fromEvent } = rxjs;
const { map, debounceTime } = rxjs.operators;

const input = document.getElementById("search");

fromEvent(input, "input")
	.pipe(
		map(e => e.target.value.trim()),
		debounceTime(300)
	)
	.subscribe(term => console.log("Search:", term));

6. 非同期処理

Observable と Promise の違い

  • Promise: 通常は1回だけ値を返す。
  • Observable: 複数回値を流せる。unsubscribeで中断できる。

RxJSのajaxでAPI呼び出し

const { ajax } = rxjs.ajax;

ajax
	.getJSON("https://jsonplaceholder.typicode.com/users")
	.subscribe({
		next: data => console.log("Users:", data),
		error: err => console.error("HTTP error:", err),
		complete: () => console.log("Completed")
	});

7. エラーハンドリングと完了処理

const { of } = rxjs;
const { catchError, retry } = rxjs.operators;
const { ajax } = rxjs.ajax;

ajax
	.getJSON("https://api.example.com/data")
	.pipe(
		retry(2),
		catchError(err => {
			console.error("Request failed:", err);
			return of([]);
		})
	)
	.subscribe({
		next: data => console.log(data),
		complete: () => console.log("Finished")
	});

ポイント:

  • catchError: エラー時の代替処理。
  • retry: 失敗時に再試行。
  • complete: 正常終了時に実行。
  • unsubscribe: 手動で停止。

8. ベストプラクティス

  • 無限ストリーム(interval, fromEvent)は購読解除する。
  • pipeでオペレーターを読みやすく連結する。
  • 重い処理をsubscribeに詰め込みすぎない。
  • tapでデバッグすると流れを追いやすい。

9. 最終プロジェクト(提案)

ライブ検索ミニアプリ:

  1. テキスト入力を作る。
  2. fromEventで入力イベントを監視。
  3. map + debounceTimeを適用。
  4. ajax.getJSONでAPIを呼ぶ。
  5. 結果を画面に表示。
  6. catchErrorでエラー処理。

これで基礎内容を1つの実践フローで確認できます。

10. 参考リンクと次のステップ

公式ドキュメント:

おすすめ練習:

  1. intervalでストップウォッチ。
  2. + / - ボタンのカウンター。
  3. 公開APIを使ったライブ検索。
  4. retryによる再試行処理。

次の学習:

  • 中級編で switchMapmergeMap、Subject、ストリーム合成を学ぶ。