Help us understand the problem. What is going on with this article?

RxJSをはじめる

More than 1 year has passed since last update.

RxJSをはじめる

by maaz118
1 / 19

RxJS? :thinking:


reactivex.io

スクリーンショット 2017-05-25 18.47.33.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

// 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にエラー時のコールバックを書く
promise
  .then(data => ...)
  .catch(err => ...);

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

Observable

  • subscribeがコールバックを3つとる
    • onNext, onError, onCompleted
observable.subscribe(
  data => ..., // Promise.then
  err => ..., // Promise.catch
  () => ... // Promiseにはない
// Observableが途切れたときのonCompletedコールバック
);

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

Observableとイベント

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:

        _人人人人人人人人_
        > まぎらわしい <
         ̄Y^Y^Y^Y^Y^Y^Y ̄

基本的なやつ

  • map, filter
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からユーザー情報を取得して、そのユーザーが担当になっている面接を取得する
http.get('/api/account')
  .map(data => data.json())
  .mergeMap(me => http.get(`/api/interviews/${me.id}`)
  .map(data => data.json())
  .subscribe(interviews => ...);

マーブルダイアグラム

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

img


marble testing

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

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


Rxやるしかない :muscle:

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

おわり

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away