水無瀬のプログラミング日記

プログラムの勉強した時のメモ

RxJSまとめ #1

TL;DR.

ソースコード
動作サンプル

はじめに

Angularを使っているので、RxJS自体は嫌でも使っていた。
必要なときに必要そうなものを検索して使っていただけなので、いい加減まともに勉強する。

RxJSとは

RxJSは'Reactive Extensions for JavaScript'の略。
Observablesと言うアーキテクチャを用いたリアクティブ・プログラミング用のライブラリである。

便利な点

  • 非同期処理やイベント処理を簡単に書ける
  • エラーおよび終了を上手くハンドリングできる
  • 関数型のコレクションライブラリのようなもの

そもそもRxとは

Rx(Reactive Extensions)はERP(関数型リアクティブプログラミング)を実現するライブラリ。
もともとはMicrosoftが.Netで開発したもの。
現在はMicrosoft以外にもNetflixが様々な言語に移植している。

サンプルコード

// 既存のボタンイベント設定
const button1 = document.getElementById('button1');
button1.addEventListener('click', () => {
    console.log('Cliked!');
});

// RxJSを用いたボタンイベント設定
const button2 = document.getElementById('button2');
fromEvent(button2, 'click').subscribe(
    () => {
        console.log('RxJSClicked!!');
    }
);

上記ではボタンクリックをしたら、クリック数をコンソールに出力するもの。
fromEventオペレータを使用し、ボタンのクリックイベントを取得。
取得したイベントデータをsubscribe(購読)メソッドを使って取り出す。
これだけだとあんまり良くわからないから細かい特徴とかまとめる。

特徴

Purity

RxJSで値を返すときは、pureな関数を通ってくる。
そのためバグが起こりにくいよと公式サイトに書いてあった。
下記の例ではscanがpureな関数なので、問題ない。
(scanが本当にpureかみたいな話を見たことがある気もするけど)

サンプルコード

// 既存
let count = 0;
const button3 = document.getElementById('button3');
button3.addEventListener('click', () => {
    console.log(`oldCount:${++count}`);
});

// RxJS
const button4 = document.getElementById('button4');
fromEvent(button4, 'click').pipe(
    mapTo(1),
    scan((count, value) => count + value, 0)
)
.subscribe(
    (count) => {
        console.log(`RxJSCount:${count}`);
    }
);

Flow

RxJSにはobservableを制御する多くの関数が用意されている。
下記サンプルコードではカウントボタン押下に1秒のインターバルをセットする例。
連打してもカウントが増えないことが確認できるはず。

サンプルコード

// 既存
let count = 0;
const rate = 1000;
let lastClick = Date.now() - rate;
const button5 = document.getElementById('button5');
button5.addEventListener('click', () => {
    if (Date.now() - lastClick >= rate) {
        console.log(`Clicked ${++count} times`);
        lastClick = Date.now();
    }
});

// RxJS
const button6 = document.getElementById('button6');
fromEvent(button6, 'click').pipe(
    throttleTime(1000),
    mapTo(1),
    scan(count => count + 1, 0)
)
    .subscribe(count => console.log(`Clicked ${count} times`));

Values

RxJSを使うとObservableを通ってきたデータを変換することができる。
下記サンプルコードはクリックしたときのマウスのX軸位置を取得する。

サンプル

// 既存
let count = 0;
const button7 = document.getElementById('button7');
button7.addEventListener('click', (event) => {
    count += event.clientX;
    console.log(`position x: ${count}`)
});

// RxJS
const button8 = document.getElementById('button8');
fromEvent(button8, 'click').pipe(
    map(event => event['clientX']),
    scan((count, clientX) => count + clientX, 0)
)
    .subscribe(count => console.log(`position x by RxJS: ${count}`));

まとめ

ざっくり概要に書いてある特徴をまとめました。
これをまとめただけだけど、思ったより長くなったから複数回に分けます。
それでは、今回はこの辺で。

参考サイト