Reactive Programming with JavaScript

#はじめに
JavaScriptを触るなかで関数型リアクティブプログラミング(FRP)について知り、面白そうと調べましたが考え方のベースとなる部分を理解することに苦労したので記録として残します。

# What is Reactive?
アプリケーションは多くの**モジュール**によって構成されています。多くの場合、そのモジュール達はデータによって繋がっています。あるモジュールの値が更新されると、他のモジュールの値も更新されるようなシーンです。
![Untitled Diagram.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513383/2835a43d-c350-fc03-87ae-1e4baa455b9f.jpeg)

例としてAmazonのようなオンラインショッピングサービスを提供するアプリケーションを挙げ、アプリケーション内の**『カート』**を担当するモジュールと、**『請求書』**を担当するモジュールの2つの関係に注目します。例えばユーザーがカートに商品を追加したとき、請求書は商品の金額に応じて自動で更新されます。つまり図の矢印はデータの流れを表していて、カートのデータが更新されると請求書のデータも更新されることを表現しています。このとき請求書はプログラム的にどのように更新されるのか、**Cartモジュール側**がInvoiceモジュールの値を更新しているのか、**Invoiceモジュール側**がCartモジュールの値の変動を監視して自力で変更しているのか考えてみます。**Reactiveなプログラミング**の場合、後者がそれと言えます。

*Reactive ProgrammingとはInvoiceモジュール側がCartモジュールの値の変動を監視して自力で変更しているようなプログラム*

つまり外部のモジュールの変更を監視し、自身のデータを更新します。前者とは違い、モジュールの値の更新を他のモジュールに依存していません。ちなみに前者のようなプログラミングをAndré Staltz（**cycle.js**を作ったエンジニア）はモジュールの外部のデータに対する受動的な姿勢から**Passive Programming**と名付けています。次に何故このリアクティブプログラミングが近年注目されているのかを示していきます。

# Why Reactive Programming?
下の図のように6つのモジュールから構成されるアプリケーションがあるとします。
![Untitled Diagram (3).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513383/5072dc98-be3a-9970-885c-cc6e64a2501f.jpeg)
このアプリケーションの挙動を理解しようとしたとき、各モジュールのコードを読んでいくことになると思います。その中でCのモジュールを読んでいるとします。先ほどの**Passive Programming**の場合、Cのモジュール内で扱っているデータがどこから来ているのかが分かりません。つまりCのモジュールを見ただけではCの挙動を理解できないのです。Aのモジュールを見ないと理解できません。加えてAのようなモジュールがどこに存在するか探す作業もあります。
**Reactive Programming**の場合、CのモジュールはAのモジュールを監視していて、Aが変更されるたびにCのデータは更新されます。従ってCを見るだけで、Cの挙動が理解できるわけです。つまり分かりやすいというメリットがあります。これ以外にも先ほどのアマゾンの例と似ていますが**検索候補**（search suggestion）のようにinputの値が更新されるたびにサーバーにアクセスすることなくreactiveに検索候補を挙げてくれるプログラムを実現できるというメリットもあります。（次のエクセルの例も参考にしてみて下さい。）
ただここで疑問になるのが、他のモジュールのイベントを監視し、反応するリアクティブプログラミングはどうやって実装されるのか、です。

# What is Reactive Programming?
モジュール自身で他のモジュールのデータの変更に対応しようとしても、他のモジュールのデータをフェッチするような関数を作成し他のモジュール側で実行しても**Reactive**とは言えません。Reactiveなプログラミングを実装するのは結構大変なのです。では、どうやって実装するのか、どういうものが**Reactive Programming**と言えるのか。まずはリアクティブプログラミングの具体的なイメージから入りましょう。
**Reactive Programming**を用いたアプリケーションとして有名なものに**エクセル**があります。エクセルをイメージすると仕組みが理解できると思います。
![Untitled Diagram (4).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513383/145c936e-bf14-15b9-959b-b38401d47164.jpeg)
例えば上の図を見たとき**赤丸**の部分が何を意味しているのか『-2』という値だけでは分かりません。エクセルではセルをクリックすると、どこのデータを**フェッチ**してきているのか一目で分かります。
![Untitled Diagram (5).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513383/fe3c15f0-6f35-6a19-035e-ed6248e9ddd7.jpeg)
このように、どのセルからデータをフェッチしているのか一目で分かります。また**『B3』のセル**のデータを変更すると自動で赤丸部分の値が更新されます。見れば分かりますが、赤丸部分のデータの更新は『B3』『B9』のセルに依存しておらず、そのため赤丸部分の内容を見るだけで挙動が理解できます。このセルたちをモジュールに置き換えたものが**関数型リアクティブプログラミング**(FRP)であり、これをコードに置き換えることで実装できます。それでは実際にコードで実装していきましょう。

# How to Reactive Programming?
今回は**rxjs**というライブラリを用いてリアクティブプログラミングを実装していきます。rxjsはコードを分かりやすいものとするために様々な役割を用語として定義しています。rxjsを用いてリアクティブプログラミングを実装するのには理解が必要な用語がいくつかあります。

![Untitled Diagram (11).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513383/c05edb4d-ce88-c9a9-2824-67ec0ce2f943.jpeg)


###observable
いつ更新されるか分からないデータを含め全てのデータをストリーム（データの流れ）とし、そのデータのストリーム自体をラップするものをRxjsではobservableと呼ばれます。エクセルのセルのようにデータをラップするものです。例えばDBのデータをラップすることで、**DBが変化するごとにリロードせずとも**対応できます。ただし関数が呼び出されない限り動かないように、observableもsubscribeされない限り何も返しません。また複数の返り値を返すことができます。

###subscribe
observable内にあるデータが更新されたとき、observerに対して知らせる役割を持つ。Youtubeのsubscribe機能が分かりやすいと思います。ユーザーは自分の好きなYouTuberに対して**subscribe**することでYouTuber（observable）の動画投稿の動き（データストリーム）を監視（listen）することができます。よく購読と訳されるのは、恐らくobservableをsubscribeすることで初めて購読（中身のデータを扱えることが）できるためだと思います。
observableをsubscribeするとsubscriptionオブジェクトを返し、これをunsubscribeしない限りobserverはobservableからデータを受け取り続けます。

###pipe
実際にobsevableのイベントに対してreactする部分。operatorと呼ばれる、データに対し予め決められた操作のできる関数を用いてデータを操作(manipulate)します。

###observer
新しいデータをobservableから受け取ったときに、それに対して処理等を行うのがobserverオブジェクトです。observableからのデータのconsumer。
3種類のコールバックを用意することができます。observableからの通知のようなものです。

 - **nextメソッド**は新しいデータをobservableが受け取るたびに実行されるメソッド。
 - **errorメソッド**はobservableがエラーを投げたときに実行されるメソッド。
 - **completeメソッド**がobservableの更新が完了したときに実行されるメソッド。

エクセルのセルに対するデータの入力、更新に終わりがないようにobservableが決して完了しないケースもあります。つまりcompleteメソッドが必要ないことがあります。

###subject
observableと似ているが、多くのobserverに対して変更を**マルチキャスト**することができます。つまり多くのobserverを持つことができるとも言え、Reactで言えばReduxと概念は似ていると思います。

###rxjsを使うメリット
operatorの数が多い
処理のフローが分かりやすい
データを自由に加工できる

##Example

```react:App.js
import React, { useState, useEffect } from 'react';
import { from  } from 'rxjs';
import { map, filter, mergeMap, delay } from 'rxjs/operators';

// observableを作成
let numberObservable = from([1, 2, 3, 4, 5]);

// operatorでobservableからのデータを操作
let squareNumbers = numberObservable.pipe(
    filter(val => val > 2),
    mergeMap(val => from([val]).pipe(
        delay(1000 * val)
    )),
    map(val => val * val)
);

// observableフックの作成。
// unsubscribeしなければデータストリームが止まらない限り実行され続ける
const useObservable = (observable, setter) => {
    useEffect(() => {
        let subscription = observable.subscribe(result => {
            setter(result);
        });
    
        return () => subscription.unsubscribe();
    }, [observable, setter]) 
}

const App = () => {
    const [currentNumber, setCurrentNumber] = useState(0);

    useObservable(squareNumbers, setCurrentNumber);
    
    return (
        <div className="app">
            Current number is: {currentNumber}
        </div>
    );
}
 
export default App;
```

#おわりに
誤字、誤った説明があった場合、お手数ですがコメント等下さい。

#参考
https://www.youtube.com/watch?v=KOjC3RhwKU4&t
https://www.youtube.com/watch?v=49dMGC1hM1o&t
https://www.youtube.com/watch?v=uQ1zhJHclvs&t
https://www.youtube.com/watch?v=eloMMybBVN0
https://www.youtube.com/watch?v=Tux1nhBPl_w
https://www.youtube.com/watch?v=GCPORlQDFHI
https://www.youtube.com/watch?v=Urv82SGIu_0&t