概要
プロジェクトでRxJSを使う機会があった。だいぶ前に入門しようとして挫折したが、改めてやってみて感じたことを書こうと思う。
Observable Stream?
RxJSでは、監視可能なイベントをObservable Streamとよんでいる。これはNode.jsのStreamのようなもので、データを一気に処理するのではなく、細切れの単位で読み取ることのできるもの、と理解している。そのため、どこかでデータがストップすることなく、常にデータが流れ続ける。
実装するのは難しい
ある程度概念を理解してくると、コードを読むのは容易になる。ある動作が起こったらこれをして
というようなコードがそれが何であるか
というところに頭をつかうようになり、コードの量はかなりへらすことができる。あちこち修正する必要が無いので、リファクタも楽になるかもしれない。
ただ、さて自分で実装に取り掛かろうとしてみると、あれ...書けない...?
といった気持ちであった。思っていたよりなかなか手が止まってしまう。ストリームの概念を理解するのと、それをコードに起こすのに時間がかかる印象だった。しかし、いつの間にか実装ができているような感じがあって、コードも少ないので、書き終わった時には気持ち良い。もっと慣れると、実装内容によっては、命令的なコードよりスピードは上がりそうだと感じたが、学習が必要だと感じる。そのため、保守はしやすくなるかもしれないが、前提として、かなりスキルを求められることと思う。
MVI
現在のプロジェクトでは、MVI(Model・View・Intent)な設計を使っている。これはRxを使うと非常にうまくコードを分割できる。
それぞれの責務
Intentがユーザーから発生したイベント、DOM操作などを、意味のある要求に変換するもの、という理解。例えば、ボタンのクリックイベントを、パネルの開閉をしたいらしい
という要求を意味したObservableに変換するようなイメージ。よって、基本的には、ここを起点にObservableがつくられることになる。その後、Modelがそれを取りまとめて、アプリケーションの状態を伝え、Viewは、データ構造を描画する元になる。仮想DOMにはReactをつかっているが、意味のあるデータ構造をそのまま移しだす
というイメージで、通常ロジックははいらない。
RxJSを開発しやすくするもの
以前RxJS(5.x)で行うテストファーストな機能開発でも書かれたが、このやり方で非常にテストファーストな開発をすることができる。また、Rxの理解しにくい部分をひとつひとつ検証できるという意味で、テスト(とTypeScript)があるとかなり有益に思えた。僕自身の理解もまだ浅いため、逆にないと不安でもある。
とはいえ、最初はマーブルでのテストを理解するのに時間がかかったので、ざっくりと説明をしてみる。例えば、以下の様なマーブルを考える。
"---a"
これは、30frame目にa
というデータがemitされることを表している(frameというのはmillisecondを模したもの)。次に、以下の様なマーブルを考える。
"---a", { a: 'R' }
これは、a
というデータにはR
というstringが入っていることを表している。つまり、30frame目にR
がemitされる。同じように考えると、以下の様なマーブルが作れる。
// 30frame目に`R`、50frame目に`x`
"---a-b-", { a: 'R', b: 'x' }
これを検証したい時に、もうひとつマーブルをつくって、照らしあわせてテストをする。イメージとしては以下の様な感じである。このコードは動かないので、実際のテストコードはこちらで確認してみて欲しい。
// toBeの中が期待されるObseravable
expect("---a-b-", { a: 'R', b: 'x' }).toBe("c--d-e-", { c: '', d: 'R', e: 'Rx' })
まとめ
初学者的な観点でRxJSの雑感を書いてみた。参考になると嬉しい。
参考
- The introduction to Reactive Programming you've been missing
- RxMarbles: Interactive diagrams of Rx Observables
- RxJS Advent Calendar 2015 - Qiita
- cycle.jsでのMVI分割時にどう考えてるか - ✘╹◡╹✘
- エディタの実装をcycle.jsでMVIベースにしてみた話 - ✘╹◡╹✘
- Rx(JS)に入門する前に知っておきたいN個のこと | MMMブログ
- RxJS(5.x)で行うテストファーストな機能開発
- なぜReactive Extensionsを導入するのか? | MMMブログ
(元記事)