RxJS
※下記の内容に不備がありましたら、コメント頂けると幸いです。また、下記の内容をご使用頂ける場合は自己責任でお願いします。
【目次】
背景
Angular開発においてRxJSを使うことが分かったので、学んだ内容をブログにしていく。
RxJSとは?
Reactive Extensions for JavaScriptの略称です。
Observablesというアーキテクチャを用いたリアクティブ・プログラミング用のライブラリで、複雑な非同期通信やイベントのコーディングを簡単かつ可読性高くコーディングできるようにするものです。
Angularでの使われ方
外部ライブラリの一つとして使われている。
HTTPリクエストの内部でObservableを返すなどの使われ方をしている。
RxJSでの重要用語
Observableクラス
非同期データソース(ストリーム)を表すクラスで、言葉通りObserve(観察)するもの。
説明する際には川で例えられることが多い。
Subscribeした時点で流れ出します。
またデータを流すことは一度しかできません。
それに問題がある場合は、Subjectを使います。
AngularではObservableよりもSubjectを使うことが多い。
Operator
Observable(ストリーム)にある値を加工するためのメソッド群。
メソッド群にはfilter、tap、mapなどがある。
約90のオペレータがある。
代表的なオペレータについては、こちらを参考にしてみてください。
Subscribeメソッド
ストリームで流れてくるデータを受け取るメソッド。
Subjectクラス
任意のタイミングでストリーム・データを流すことができます。
またObservableを継承しているため、ストリームを参照することができています。
そして、登録されたObserverを全て保持している。
AngularではObservableよりもSubjectを使うことが多い。
Observer
Subscribeする際のオブジェクト
Schedulers
遅延操作をするなどObservablesの並行性を制御するもの。
RxJSのイメージ
RxJSはよくダムや川で表現されます。
※ダム=Subjectの表現が間違っている可能性あり
ダム【Subject(変数)】には、色々なもの【value、event】を貯める【定義、セット】ことができます。
そのダムから流れているのが川【Observable、Stream】です。ダムのスイッチを押す【クリック、テキスト入力などのアクション】ことで、ダムから川が流れ出します。
もちろん川には、ダムに貯めていた色々なものも一緒に流れています。
例えば、ダムに桃と鮎【今回はvalueのみ】が貯めてあったとします。
あなたはその内の桃だけを川から取って桃缶を製造したいと考えています。
その場合、川から桃だけを取って【filter】、桃缶を製造【map】するシステム【Operators】を作ります。
そして、システムを稼働【subscribe】させることで、実際に桃缶を製造します。
最後に、無駄にシステムを稼働させておくのは意味がないので、システムを停止【unsubscribe】させます。
これがRxJSの大まかなイメージです。
COLDとHOT
実はObservableにはsubcribeせずにデータを流す仕組みも用意されています。
COLD
上記で説明した通常のRxJSの仕組みです。
subscribeされないと値は流れないし、仮にObservableに値を流しても処理されることなく消滅してしまいます。
システムを起動(subscribe)しないと、桃(value)はそのまま流れていくようなイメージです。
また、それぞれのObservableに対して個別に値を流します。
つまり、一つのObservableに対して複数のsubscribeをした場合、それぞれのsubscribeに対して個別のObservableが複製されて割り当てられます。
パラレルワールドにもう一つの川が流れるようなイメージです。
HOT
HOTオペレータが存在するとその時点で値が流れ始めます。
もしObserがなければ、値はObservableを流れ切って最後に消滅するだけです。
Observableを継承したConnectableObservableを使用することで、いくらsubscribeしようがconnectという処理が実行されるまで値が流れることはありません。
つまり、ConnectableObservableはHOTな性質のObservableです。
例
const clock$ = Rx.Observable
.interval(1000)
.take(5)
.do(x => console.log(`do: ${x}`))
.map(x => x + 1)
.publish();
clock$.connect();
setTimeout*1;
}, 2500);
また、複数のObserverに対して同一の値を流した場合、そこでストリームが分岐して後続に同一の値を流します。
本流【Observable】から川が分岐【Observer】しており、分岐した川にはそれぞれ同じ値【value(桃、鮎)】が流れているイメージです。
参考文献:
RxJS を学ぼう #4 – COLD と HOT について学ぶ / ConnectableObservable – PSYENCE:MEDIA
用語
Reactive Extensions
MicrosoftがC#向けのライブラリとして開発したもの。
LINQが適用できるデータソースの概念を「非同期」「イベント」まで広げた技術。
従来では手間がかかった複雑な非同期処理やイベント処理、時間が関係する処理、コレクションなどをLINQの形で簡単に記述できる。
LINQ
データ加工における処理の手間を大きく解消するもの。
C#3.0から導入された。
各種のデータソース(=配列やXMLデータ、SQLデータベースなど)に対して統一的な記法を提供してくれる。
リアクティブプログラミング
データが流れるように来ること(ストリーム)に着目し、データを受け取るたびに関連したプログラムが反応(リアクション)して処理を行うプログラミングの考え方。
event
イベント。
async
非同期。
array
配列。
今後に向けて
RxJSの概念難しい。。。
実際に書いて覚える方が早く理解できそう。
参考
素晴らしい記事に感謝いたします。
RxJS を学ぼう #1 – これからはじめる人のための導入編 – PSYENCE:MEDIA
RxJS を学ぼう #5 – Subject について学ぶ / Observable × Observer – PSYENCE:MEDIA
Reactive Extensionsの概要と利用方法(1/2) - @IT
RxJava - リアクティブプログラミングとは - 22時に寝ようと思って2時に寝る。
リアクティブプログラミングとRxJavaの概要 (1/6):CodeZine(コードジン)
AngularのRxJSを使ってデータの受け渡しをする - Qiita
*1:) => {
clock$.subscribe(x => console.log( `B: ${x}`