この記事は bouzuya's RxJS Advent Calendar 2015 1 日目かつ RxJS Advent Calendar 2015 の 1 日目です。
RxJS とは何か?
RxJS とは The Reactive Extensions for JavaScript のことです。これは Reactive Extensions の JavaScript 向けの実装です。
Microsoft Open Technologies, Inc. により開発されています。
公式のリポジトリは Reactive-Extensions/RxJS にあります。v5 (alpha) は ReactiveX/RxJS にあります。
Reactive Extensions (Rx) とは何か?
もともとは C# 向けのライブラリです。各言語向けに実装が提供されています。ここでは RxJS (v4.0.7) を前提として書いていきます。
RxJS = Observables + Operators + Schedulers.
まず公式のリポジトリの README にある簡単な説明では RxJS は次の要素からなると説明されています。
RxJS = Observables + Operators + Schedulers.
- Observable …… 非同期データストリームを表現するもの。
- Operator …… Observable に対して map や filter をはじめとするクエリーを適用するもの。
- Scheduler …… 並行性を制御するもの (適当) 。
ちなみに C# では Rx = Observables + LINQ + Schedulers. でした。 RxJS にも同様の記述があります。
Observable は複数個に対応できる Promise
もうひとつ公式リポジトリの doc/readme.md
には Observable を同期非同期/単一値複数値という分類で説明した表があります。
Single return value | Multiple return values | |
---|---|---|
Pull/Synchronous/Interactive | Object | Iterables(Array/Set/Map) |
Push/Asynchronous/Reactive | Promise | Observable |
Observable は、複数値を受け取れる Promise で、非同期に対応した Iterable に相当するものということです。
ぼくはこの位置づけは Node.js の Stream と近いと思っています。これらの違いについては別で書くかもしれません。
Pull / Push および Interactive / Reactive という分類を、ぼくは能動的・受動的なイメージでとらえています。pull media / push media のそれです。 Pull は Google での 検索のように利用者側が供給側に情報を取りに行くイメージ、 Push はテレビのように供給側から利用者側に送りつけるイメージ。RxJS では Observable を subscribe
で observer
を登録します。この詳細はまた別のタイミングで。
簡単な例
次の例は RxJS の簡単な例です。Observable
を返す fetchUsers
を使っています。各 user が非同期 (例えば 100 ms ごとにひとりずつなど) に流れてきても問題なく console.log
が呼び出されます。
fetchUsers() // return Observable
.filter(user => user.age > 20)
.map(user => user.name)
.subscribe(name => console.log(`Name: ${name}`));
RxJS の良いところ・悪いところは何か?
まず Observable により「時間軸とそこを流れるイベント」をコレクション (シーケンス) としてとらえているというアイデアが良いです。
Operator により、非同期処理への対応を collection を操作するようなインタフェースでできます。複数の Observable を merge することも簡単です。
悪いところは、 Array より EventListener より Promise よりずっと複雑であること。当然です。非同期で複数値を相手にしているからです。そして便利なたくさんの Operator は初学者を絶望させるに十分です。きっと Observable に生えた Operator の山を見てドキュメントを閉じたくなるでしょう。
それでもこのコンセプトには学ぶ価値があると、ぼくは信じています。