angular
RxJS
ionic

RxJSをはじめよう 〜FetchからSubject queueに至るまで〜

「Ionicで作る モバイルアプリ制作入門」刊行記念 Ionic Meetup Tokyo #3

https://ionic-jp.connpass.com/event/74895/

2018年1月28日


今回のサンプルコード

https://github.com/ovrmrw/ionic-subject-queue


自己紹介

ちきさん (Tomohiro Noguchi)

Qiita/Twitter/GitHub: @ovrmrw

市ヶ谷にあるオプトという会社で働いています。

3a2512bb-aa72-4515-af42-1f1721252f39.jpg


初めてRx(C#)に触れたときの感想

  • 解説しているブログとか読んでも、なにをいっているのかさっぱりワカラナイ。
  • hotとかcoldとか意味不明。
  • flatMapとか異次元すぎる。
  • ようやく到達した理解が「Rxはイベントハンドリングするためのライブラリ」だった。

初めて理解したRx(C#)

Observable.fromEvent

  • テキストボックスの入力イベントをハンドリングし、何らかの処理に繋げられる。
  • debounceを使うことでイベントを間引くことができる。

===

初めてObservable.fromEventを使って書いたコードが動いたときはかなり感動しました。


なのでObservable.fromEventを織り交ぜたLTをすればRxJSの良さをより伝えられるのではないかと考えた。


ここから本編


Ionicにおける代表的なRxJSを使うパターン


HttpClient と AsyncPipe

  • これらは使い手が意識しなくても非同期処理をObservable空間に閉じていい感じに自動キャンセルとかしてくれる。
  • 後始末(unsubscribe)を勝手にやってくれる。
  • 組み合わせて使っておけばそれでだいたいオッケー。

HttpClient と AsyncPipe に足りないもの

  • 入力を間引く仕組み。(debounce)
  • 例えばキーボード入力に応じて検索を実行する場合、「ionic」という入力に対して「i」,「io」,「ion」,「ioni」,「ionic」の全てで非同期処理(リクエスト)を発生させると最後以外は無駄になる。
  • Cloud FunctionsとかAWS Lambdaみたいな仕組みでAPIを構築している場合、無駄に多く叩かれるとうれしくない。:disappointed_relieved:
  • AsyncPipeを使うとtemplateに非同期処理を持ち込むことになるのでごちゃごちゃする。(このへんは好みの問題)

無駄の多い非同期処理から、無駄のない非同期処理まで5つのパターン とそのデモ


Ionic Viewアプリ用

public AppID: 3c5bd0d9


非同期処理のパターン 1

Fetch (AsyncPipeなし)

リクエスト投げっぱなしの最悪パターン。


Fetch (AsyncPipeなし)

  • 全ての入力が新しいリクエストを発生させる。キャンセル不可。
  • それらは並列で走る。
  • Viewへの反映が最後の入力に対する結果である保証はない。

(デモ: Fetchページ)


非同期処理のパターン 2

Fetch (AsyncPipeあり)

とりあえずキューイングを導入しただけの「無いよりマシ」パターン。


Fetch (AsyncPipeあり)

  • 全ての入力が新しいリクエストを発生させる。キャンセル不可。
  • それらはAsyncPipeによりキューイングされる。
  • Viewへの反映が最後の入力に対する結果であることは保証されるが、それまでのレスポンスを全て待たなければならない。

(デモ: Fetch with AsyncPipeページ)


非同期処理のパターン 3

HttpClient (AsyncPipeあり)

Ionic(Angular)の標準パターン。


HttpClient (AsyncPipeあり)

  • 全ての入力が新しいリクエストを発生させるが、必要に応じて自動キャンセルされる。
  • それらはAsyncPipeによりキューイングされる。
  • Viewへの反映が最後の入力に対する結果であることは保証されるし、不要なリクエストはキャンセルされるので無駄な待ちがない。

(デモ: HttpClient with AsyncPipeページ)


非同期処理のパターン 4

HttpClient with Observable.fromEvent (AsyncPipeなし)

次のSubject queueを説明するための踏み台。


HttpClient with Observable.fromEvent (AsyncPipeなし)

  • 入力イベントをキューイングすることでAsyncPipeが不要になりtemplateがスッキリする。(好みの問題ではある)
  • switchMapオペレーターの中でHttpClientを使っているので自動キャンセルは有効。
  • オペレーターを駆使することで必要以上にAPIを叩かない仕組みを作れる。
  • イベントハンドリングの記述が独特な書き方になるのでコードは読みにくい。

(デモ: HttpClient with Observable.fromEventページ)


非同期処理のパターン 5

HttpClient with Subject queue (AsyncPipeなし)

:arrow_heading_up::arrow_heading_up: 要するに今日はこれを話したかった。 :arrow_heading_up::arrow_heading_up:


HttpClient with Subject queue (AsyncPipeなし)

  • Subjectを使ってキューイングしている。
  • Observable.fromEventの例のメリットを踏襲しつつ、Angularっぽさのあるコードで読みやすい。

(デモ: HttpClient with Subject queueページ)


Subjectを使えばなんでもできる :muscle:


(おまけ) RxJS関連で書いたもの


Thanks! :raised_hands: