RxJSとはなんぞや?②イベントから observable を作成
前回、RXjSひいては『関数型リアクティブプログラミング (FRP)』はストリーム(時間軸に沿った処理すべきイベントの流れ)を中心にプログラミングしていくべきの様だとまとめましたので、実際に試してみたいと思います。
色々できそうだなと思いましたが、正直、ゲームブックアプリはこれを使わなきゃいけないほど処理がタイトなアプリにはならない気もしますので、全く別なサンプルを試したいと思います。
まずAngular公式から『イベントから observable を作成する』を試してみます。
Angular 日本語ドキュメンテーション|RxJSライブラリー
https://angular.jp/guide/rx-library
サンプルコード
---------------------------------------------------------------
import { fromEvent } from 'rxjs';
const el = document.getElementById('my-element')!;
// Create an Observable that will publish mouse movements
const mouseMoves = fromEvent<MouseEvent>(el, 'mousemove');
// Subscribe to start listening for mouse-move events
const subscription = mouseMoves.subscribe(evt => {
// Log coords of mouse movements
console.log(`Coords: ${evt.clientX} X ${evt.clientY}`);
// When the mouse is over the upper-left of the screen,
// unsubscribe to stop listening for mouse movements
if (evt.clientX < 40 && evt.clientY < 40) {
subscription.unsubscribe();
}
});
---------------------------------------------------------------
例えば、"home.page.html"にボタン(id="my-element")を用意して、import以下の部分をこのボタンを押した時に動作するようにすれば、コンソールログにマウスの位置を延々と書き出すわけです。
ここで、ちょっと用語の問題があります。
前ページで紹介したサイトの筆者によれば、Observable(公式的には単一の値のストリームを呼ぶらしい)もストリームで統一したいとの事ですが、プログラムの解釈的には今の所ストリームという用語を見たことが無いので、当面、"Observable"は"Observable"で記述したいと思います。
【翻訳】あなたが求めていたリアクティブプログラミング入門
https://ninjinkun.hatenablog.com/entry/introrxja
多分、とても役に立つサイトだと思いますがこれについては仕方ないです。
さて閑話休題
上のサンプルコードの『解読』に取り掛かりたいと思います。
まずimport文ですが、イベントから"Observable"を作成するのに必要です。
(細かな情報が必要であれば、VisualStudioCodeで右クリック→定義である程度情報取れます)
次に、一寸本題から外れるのですが、エレメント取得した時の末尾のビックリマークについての参考サイトのご紹介です。
(私は初めて知りましたので)
TypeScriptの変数の末尾の"!"(エクスクラメーション/感嘆符)の意味
https://qiita.com/zigenin/items/364264a6cf635b962542
次にimportした"fromEvent"を使い、"mouseMoves"と言う名前の"Observable"を作成します。
残りのコードを見る前に実際の動作を見ると判りますが、対象のエレメント上でマウスが動くと"mousemove"イベントが発生して、イベントが起きるたびに(つまりマウスが動くたびに)Console.Logにマウスの位置が書き込まれます。
上のサンプルの停止条件はエレメントの位置によっては満たさないので、変数を用意して上限までカウントさせた方が良いかもしれません。(subscription.unsubscribe();で停止です。)
停止条件をのぞいた動きとしては
・Idが'my-element'であるエレメント上で起きる'mousemove'イベントを監視するためのObservable"mouseMoves"を作成
・mouseMoves.subscribeで監視を開始
・またmouseMoves.subscribe()内でイベントが起きた時の動作を定義
・停止のために(多分それだけのために)mouseMoves.subscribeに"subscription"と言う名前を付けておき、停止条件を満たしたならsubscription.unsubscribe();で停止する
解読はこんな感じで良いかと思います。
ポイントとしては、イベントから作成するObservableなのでmouseMoves.subscribe()内が
evt => { 中略 }
の形になっている事だと思います。
次は(多分短くて済むと思いますが)カウンターから observable を作成する例を見ていきたいと思います。