Vanilla JavaScriptで学ぶRxJS基礎コース
1. リアクティブプログラミングとは
リアクティブプログラミングは、時間とともに変化するデータの流れ(ストリーム)を扱う考え方です。
- マウスクリックはイベント。
- 入力欄の文字入力もイベント。
- HTTPレスポンスは非同期イベント。
データが来たかを何度も確認するのではなく、届いた瞬間に反応します。
2. RxJSとは
RxJSは、Observableを使って非同期処理やイベント処理を組み立てるためのJavaScriptライブラリです。
インストール
npm:
npm install rxjsCDN:
<script src="https://unpkg.com/rxjs@7/dist/bundles/rxjs.umd.min.js"></script>Vanilla JSの基本構成
index.htmlapp.jsstyles.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, BfromEvent
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. 最終プロジェクト(提案)
ライブ検索ミニアプリ:
- テキスト入力を作る。
fromEventで入力イベントを監視。map+debounceTimeを適用。ajax.getJSONでAPIを呼ぶ。- 結果を画面に表示。
catchErrorでエラー処理。
これで基礎内容を1つの実践フローで確認できます。
10. 参考リンクと次のステップ
公式ドキュメント:
おすすめ練習:
intervalでストップウォッチ。+/-ボタンのカウンター。- 公開APIを使ったライブ検索。
retryによる再試行処理。
次の学習:
- 中級編で
switchMap、mergeMap、Subject、ストリーム合成を学ぶ。