RxJSをはじめる

# RxJS? :thinking: 

---

# [reactivex.io](http://reactivex.io)

![スクリーンショット 2017-05-25 18.47.33.png](https://qiita-image-store.s3.amazonaws.com/0/59312/7e49f63e-5a75-464a-864c-7c7a1fade6b0.png)

---
# RxJS? :thinking: 

- **Observable** ストリームによる非同期プログラミングのためのAPI
- Rx(ReactiveX)というほぼ共通のAPIでいろんなプラットフォームへの実装がある
  - Rx.NET(オリジナル), RxJava, RxJS, ...
- デザインパターンのObserverパターンがベース
- AngularはRxJS使いまくってる

---
# Observer デザインパターン
- Observable
  - 非同期に値を出すやつ
- Observer
  - その値を受け取ってなんかするやつ
- イベントとイベントリスナーみたいなやつ
- Observable ≒ JSのPromise,ScalaのFutureで値が何回も来るやつ
 
---
# PromiseとObservable

```js
// Promiseを返す
axios.get('/api/foo')
  .then(data => ...)
  .catch(err => ...);

// PromiseをObservableにできる
Rx.Observable.fromPromise(axios.get('/api/foo'))
  .subscribe(
    data => ...,
    err => ...
  );
// subscribeメソッドに成功、失敗のコールバックを渡す

// AngularのhttpクライアントはObservableを返す
http.get('/api/foo')
  .subscribe( 
    data => ...,
    err => ...
  );
```

---

# Promise

- thenに成功、catchにエラー時のコールバックを書く

```js
promise
  .then(data => ...)
  .catch(err => ...);

// こういう書き方もできる
promise.then(data => ..., err => ...);
```

---
# Observable

- subscribeがコールバックを3つとる
  - onNext, onError, onCompleted

```js
observable.subscribe(
  data => ..., // Promise.then
  err => ..., // Promise.catch
  () => ... // Promiseにはない
// Observableが途切れたときのonCompletedコールバック
);

```

- onCompleted, onErrorは省略してもよい

---
# Observableとイベント

```js
document.addEventListener('click', ev => ...);

Rx.Observable.fromEvent(document, 'click')
  .subscribe(ev => ...);
```

---
# RxJSの特徴

- 非同期のイベント管理に強い
  - inputへの入力を500msスロットルしてAPIのこことあそこに投げた結果を待ち受けて成功だった場合だけ結果をくっつけて文字列にして返すObservable

---
# RxJSの特徴

- Observableに死ぬほど(120個くらい)メソッドが生えてる :innocent:
- Observableの亜種が10個くらいある
  - Subject, AsyncSubject, ...
- 学習コストは高い
  - hot, coldの概念とか
- その分メソッドチェーンがキマると気持ちいい
- メソッドが死ぬほど生えてるということは型やIDEによる補完が無いと死ぬ
  - TypeScriptで再実装された

---
# 再実装？ :thinking: 

- https://github.com/Reactive-Extensions/RxJS
    - v4まではこっち
    - JavaScript
- https://github.com/ReactiveX/RxJS
    - v5以降はこっち
    - TypeScript

<pre>        ＿人人人人人人人人＿
        ＞　まぎらわしい　＜
        ￣Y^Y^Y^Y^Y^Y^Y￣
</pre>

---

# 基本的なやつ

- map, filter

```js
Rx.Observable.from([1,2,3,4]) // 1,2,3,4
  .filter(x => x % 2 == 0) // 2, 4
  .map(x => x * 10) // 20, 40
  .subscribe(x => console.log(x))
// 20
// 40
```

---
# ありがちなやつ

- APIからユーザー情報を取得して、そのユーザーが担当になっている面接を取得する

```js
http.get('/api/account')
  .map(data => data.json())
  .mergeMap(me => http.get(`/api/interviews/${me.id}`)
  .map(data => data.json())
  .subscribe(interviews => ...);
```

- ScalaでいうflatMap的な
  - `concatMap`, `mergeMap`, `switchMap` など似たようなのがある :innocent: 
  - refer: http://qiita.com/ovrmrw/items/b45d7bf29c8d29415bd7

---
# マーブルダイアグラム

RxのObservableストリームの図示によく使われる

![img](http://reactivex.io/rxjs/img/map.png)

---
# marble testing

コードでマーブルダイアグラムを書いてテストするおしゃんな仕組み

```js
const e1 = hot('----a--^--b-------c--|');
const e2 = hot(  '---d-^--e---------f-----|');
const expected =      '---(be)----c-f-----|';

expectObservable(e1.merge(e2)).toBe(expected);
```

---
# rxjsをREPLっぽくさわる

- ビルドされたRxJSをロードするhtmlを書いて、Chromeで開いてDeveloper Console
  - なぜか補間が割と効いてくれる
  - `<head>` の中に `<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.4.0/Rx.js" type="text/javascript"></script>`

![スクリーンショット 2017-05-26 13.41.00.png](https://qiita-image-store.s3.amazonaws.com/0/59312/2c5a5176-c93e-362b-5069-03ff10a9bd22.png)

---
# Rxやるしかない :muscle: 

- AngularはRxJSまみれ
- RxJavaはAndroidとかでよく使われるらしい
- Java9で標準APIに入るReactive StreamsはRx + back pressureみたいのらしい？

---

# おわり