RxJavaの勉強会があったので軽くメモを残しておきます。
Voyageさんでの勉強会でしたが、色々有名な方もいらっしゃってました。
Rx注目されている証拠ですね。
実際のアプリ開発で使ったRxを紹介(by Yuki Funakoshi)
基本的な話
- 非同期処理のコンポーネント
- イベントベースプログラミング
- ObservableとSubscriberのやり取り
- リストビューが多い。
just
Observable.just(sharedPreferences.getBoolean(KEY_ENABLE, true))
filter
Observableで帰ってくる値からフィルタリングして一部のみ返す。
いいねボタンのresponseが返ってきた際の処理
.map()
.startWith(()->{
return fakeRecommend
})
キャッシュ
キャッシュがない場合はapiから取得する。
doOnNext
interfaceでキャッシュするための機能を追加して、doOnNextのレスポンス時にキャッシュを取得
ReactiveXのドキュメントにある図の見方の解説(by yanzm)
Rx = ReactiveX
- 矢印 - Observableのタイムライン
- アイテム - Observableによって出力されたアイテム(左->右の流れ)
- 縦棒 - Observableが完了したことを表示する。(onCompleted)
- 四角いboxと点線 -> Observableに変換できることを表現している。
- ×印 -> Observableで何かに失敗したことを表す。(onError)
Methods
Just
itemが一個出て一個出る。errorが呼ばれる余地がない
From
リストを渡すとリストの順番で吐き出される。
Create
Operatorに何も渡さない。
onNext(🔴); onNext(🔵); onComplete()
Defer
SubscribeされるまでObservableを作らない。各Observable
毎回作り直して、吐き出している。
Map
map(x -> 10*x)
値に適用しているだけ
FlatMap
Observableによって出力されたアイテムを複数のObservableから単一のObservableに平坦化する。
注目するのは、緑と青のひし形の順番が前後する。
Filtering
特定の条件に応じてフィルタリングする。
distinct
重複をフィルタリングする。
first
最初のアイテムが呼ばれたときにonCompletedが呼ばれる。
last
onCompleted()の際に、一番最後のitemがObservableで吐き出される。
Debounce
出力されてから一定の時間がたったものだけを出す。
一定時間を出す前に次のアイテムが出力されたら、そのアイテムが吐き出される。
ユーザーがテキストを変更して、100ms後に変更したい場合などに利用する。
Zip
二つのアイテムが揃えば次のObservableにわたる。
CombineLatest
combineLatestの場合は2つ揃ってなくても、一つでもアイテムが揃えば、アイテムを吐き出す。
merge
渡すデータ型が同じではない場合はあまり使わない。(オブジェクトを用意しないといけない。)
switch
単一のObservableにおいて、複数のObservableが吐き出される場合に、そのストリームを単一のObservableにする。それらに含まれるitemは最新のアイテムが吐き出される。
catch
OnError()をコールバックしないで、errorのObservableのアイテムを吐き出す。
「RxJava + Vert.x + jOOλ で Microservice 的な何かを作ってみた(業務的に) 」by chimerast
iOSだったのでとばしてしまいました。笑
Tapping Retry(by hydrakecat)
Observableがでリクエストが失敗した際に、再度リクエストしたいときに便利なメソッドが存在する。
・repeatWhenとretryWhen()の使い方
・notificationHandler
Observable.create(new OnSubscribeThrowError())
.retryWhen(notificationHandler)
.subscribe(i -> {
// do something
}, System.err::println);
Notification Handler
Arguments: Observable<Throwable>
Return: Observable<?>
実際のユースケース
- Delayed Retry -> 遅らせてRetryしたいときに利用
retryWhen(observable ->
observable.flatMap(throwable ->
Observable.timer(5. TimeUnit.SECONDS)
)
)
- Resubscribe a limited number of times with zip and range
-> 上限の回数だけresubscribeする。
retryWhen(observable ->
observable.zipWith(Observable.range(1, 3), (n, i) -> i)
)
- Exponential backoff -> データ送信処理が失敗して再送信するときに、失敗回数が増えるに連れて再送信するまでの待ち時間を指数関数的に増やす
retryWhen(observable ->
observable.zipWith(Observable.range(1, 3), (n, i) -> i
.flatMap(retryCount ->
Observable.timer((long) Math.pow(5, retryCount), TimeUnit.SECONDS)
)
)
)