書こうと思ったきっかけ
Angularをさわりはじめて半年以上経ちましたが、実務で成り行きで使っていたところもあり、一度基本に立ち返り基礎的な部分をまとめてみようと思いました。
RxJSとは
非同期処理やイベントハンドリングを扱いやすくするためのライブラリで、Angularに標準装備されています。
RxJSを使うメリット
-
非同期処理を容易にできる
Angularの場合はTypeScriptなので、Promise,async/awaitがあるので、そこまで容易にできると感じた
ことはないですが、一応メリットにはなるかと思います。 -
メソッドチェーンによるシンプルな記述
オペレータと呼ばれるメソッドチェーンをつないでデータを処理、加工しますが、ネストが深くならないので、
読みやすいです。
処理の流れ
処理の流れとしては、
1.ストリームの生成
2.データの加工
3.データの処理
の順で行われます。それぞれについて、詳しく書いていきます。
1.ストリームの生成
RxJSの処理の流れは、よく川の流れに例えられます。
まずは、データを川に流してあげる必要がありますが、それを行なうのが、下記のようにストリームを生成します。
// ①of
// 引数を幾つでも持つことができます。引数をそのまま流します。配列は持てません。
const observableOf = of(1,2,3);
observableOf.subscribe(data =>
console.log(data));
// 結果
// 1
// 2
// 3
// ②from
// 引数に配列を持つことができます。配列要素を順次流します。
const observableFrom = of([1,2,3]);
observableFrom.subscribe(data =>
console.log(data));
// 結果
// 1
// 2
// 3
// ③interval
//データを流す間隔(msec)を引数にとり、指定した間隔ごとにデータを流します。
//注意点としては、どこかで止めないと永遠に流れ続けるので、takeで止める必要がある。pipe,takeについては後述する。
const observableInterval = interval(1000);
observableInterval.pipe(take(5)).subscribe(
(t) => console.log(t));
// 結果
// 0
// 1
// 2
// 3
// 4
2.データの加工
次は流れてきてデータを加工します。もちろん、加工しない場合はここは不要です。
少しだけオペレータを紹介しますが、JSの配列が持っているメソッドと使い方が似ているので、難しくはないかと思います。
また、基本的にはrxjs6以降、オペレータはpipeメソッドの引数に渡さなくてはなりません。
// ①map
// ストリームから流れてきたデータを一つずつ関数に渡していきます。
const numsMap = of(1, 2, 3)
numsMap.pipe(
map((n) => n * n))
.subscribe((o) => console.log(o));
// 結果
// 1
// 4
// 9
// ②filter
// ストリームから流れてきたデータは、条件に合うものだけを次の処理に渡します。
const numsFilter = of(1, 2, 3, 4, 5, 6)
numsFilter.pipe(
filter((n) => n % 2 === 0))
.subscribe((o) => console.log(o));
// 結果
// 2
// 4
// 6
// ※随時、追加していきます。
3.データの処理
最後にデータの処理です。加工されたデータが最終的にはここに行き着き、ストリームの終端になります。
既に出てきていますが、データを受け取るためにsubscribeを使います。
subscribeは通常は引数は一つだけですが、3つ受け取れるようになっています。
subscribe(next, error, complete)
next, error, completeの3つはそれぞれ、下記のように使用されます。
next
通常時に使用する。ストリームから流れてきた数だけ処理する
error
ストリーム内でエラーが発生した際に呼び出される。
complete
正常に終了した場合に呼び出される。
const numsMap = of(1, 2, 3)
numsMap.pipe(
map((n) => n * n))
.subscribe(
o => console.log(o),
err => console.error(err),
() => console.log("complete")
);
また、subscribeの他にunsubscribeというものもあり、これはデータの受け取りを終了させるためにあります。
データの個数があらかじめわかっている場合や、takeオペレータを使って終了条件が定義されていればunsubscribe不要ですが、
(自動的にunsubscribeが呼び出されている)intervalオペレータ等はデータの終わりががないため、指定がない限り永遠に待ち続けます。
ここについては別記事で詳しく書く予定です。
参考にした記事
https://qiita.com/FumioNonaka/items/b625ab4373de38beb2ed
RxJS 入門 著者 ponday_dev様