Observableってなんなんね?
ついにRCのリリースも間近となったAngular2ですが、私はこの間のハンズオン以来全然触れてません。
少しづつ触っていきたいものですが、ここ最近の勉強会の経験からAngular2を学ぶならWebの最新技術を学ぶことが大切なのだとわかったので、まずは、Observableを調べてみようと思います。
学習教材を探す
Observableについて学ぶぞ!と意気込んでみたもののどうやって学べばいいのでしょう。
どこかにObservableの正体について書かれた資料はないでしょうか。
ここにObservableがリストアップされています。
TC39、ECMAScriptを策定してる組織です。ECMAScriptはJavaScriptの仕様だと前に教えてもらったことがあります。
- どういう人達なのか
- 何が目的なのか
- そのために何をしているのか
思うことはいろいろありますが、とりあえずこの辺りはおいておきます。ecma262、これはなんでしょう。
なるほどECMAは組織でした。そのECMAが管理する仕様には管理番号が割り振ってあります。
つまり、ecma262はECMAが管理する仕様の一つということになりますね。
(ということはTC39のメンバーはECMAの人たちで構成されているのでしょうか?)
話を戻します。例のリポジトリにリストアップされたObservableのリンクを辿ってみます。
ありました。Observableの仕様を見つけることができました。以降はこの仕様を元に学習しました。
Observableの提案の概要がまとめれています。
Observableとはなんだろう
ObservableはDOMイベント、timer intervals、 そしてsocketsのようなpush-basedデータソースをモデル化するのに使われます。
- Compositional: Observablesは、higher-order combinators(?)で組み立てられる
- Lazy: Observerがsubscribeするまで、Observablesはデータを発信し始めません
粗末な翻訳は許して下さい。英語苦手なんですよー。typeを型と訳すならObservableはどうやら型のようです。
JavaScriptにはECMAScriptで定められたプリミティブな型がすでにあります。
- Boolean
- Null
- Undefined
- Number
- String
- Symbol (ECMAScript 6で登場)
プリミティブではないものとしてObjectもありますね。
お、DOMのキーイベントを使った例があります!例示は理解の試金石です。早速見てみましょう。
この例を見る限りどうやらObservableは標準のビルトインオブジェクトとしても実装することを想定しているのでしょうか。
listenはObservableインスタンスを返し、Observableコンストラクタは関数を受け取っています。
関数はキーイベントにhandlerをアタッチして...っとhandlerの詳細がわかりません。
// observerとは何なのか let handler = event => observer.next(event);
このドキュメントにはObservableやobserverのインターフェイスについても書かれています。
それによるとこのobserver.next
はシークエンスの次の値を送り出すらしいですが...。
うーん、むずかしいです。何より何がしたいのか想像できません。
一旦この例を離れてObservableの実装例として、このドキュメントに挙がっているRxJSとzen-observableについて調べてみることにしました。
どのように動き、何がしたいのか知りたかったのでいろいろ調べていると、Observableをスクラッチで作ってみる動画を見てピンときました。
この時点でObservableとは非同期のデータの流れの手続きのことだとわかりました。
他にも以下のことがわかりました。
- Observableはsubscribeすることでデータが流れ始めること
- subscribeする際にnext, error, completeに対応した処理を記述できること
- completeしたあとではデータが流れないこと
- データを流したあとキャンセル可能なこと
- キャンセルしたあとはデータが流れなくなること
この動画に沿っての実装はとてもわかりやすいのでおすすめです。
この動画を踏まえたうえで、先ほどのObservableの仕様書の例に戻ってみます。
ここで定義されているデータの流れはHTML要素から発せられるキーイベントです。
ストリーム中のイベントを配列を扱う時のようにfilterやmapする標準のcombinatorを使うことができる。
ここで以前わからなかった翻訳の意味が何となくわかりました。
higher-order combinatorsというのはこのfilterやmapのことをいってるはずです。
まるで配列を扱う時のようにObservableにはfilterやmapが実装されているそうです。
"filter" と "map" メソッドは提案に含まれてません。この仕様の将来のバージョンで追加されるかもしれません。
ですが、今のところ提案に含まれてないようです。今後の続報に期待しましょう。
さらにsubscribe
メソッドの代わりとしてforEach
メソッドがあり、これは一つの関数を受け付け、Promiseを返すそうです。
その後のMotivationの項目を見ていろいろわかったので、少し整理してみます。
- Observableとは非同期のデータの流れを扱うプロトコル
- Observableは型になるかもしれない
- ObservableはDOMイベント、timer intervals、そしてsockets、UIに起因するような(アプリ内で起こる)データの流れをモデル化するのに使われる
- Observableはfilterやmapのようなcombinatorで組み立てることができる
- filterとmapは提案に含まれてない
- Observableはsubscribeするまで、データを発信し始めない
- Observableはビルトインオブジェクトになるかもしれない
- Observableはsubscribeしたあとunsubscribeすることでデータの流れを止めることができる
- (Observableはpush-basedのプロトコルをアプリやプラットフォームで扱えるようにするもの?)
push-basedプロトコルというのが何なのかイマイチですが、Observableがどういったものかわかりました。
JS Bin - Collaborative JavaScript Debugging
Angular2とタイプした時にconsole上でReceived key command: Angular2と出力するだけのサンプルです。
RxJSは使わず、zen-observableで実装してあります。ほとんどこの仕様書通りの実装です。よろしければこねこねしてやってください。
Observableについて理解できましたが、その強力さや凄さについては未だ疑問が残ります。
そのあたりのことは次回か、今週のng-kyotoのmeetupで話せたらいいと思っています。
興味のある方はぜひお越しください!ではではまたね!