アプリの画面表示処理などで、APIやDB等の複数のデータソースに問い合わせて、
全てのデータが揃ってからガッチャンコしたい……という事がよくある。
こういう時に今時で便利なのが、いわゆるリアクティブプログラミングで、
zipオペレータを使えば複数ソースの取得を待つことができる。
で、いざ実装しようとして調べてみると、2つのデータソースを利用するサンプルはちょこちょこ検索にHitするが、3つの場合にズバリなサンプルがHitしなかったのでここにメモ。
Triple と Function3 を使えば簡単に実現できる。書き方ややこしいけど。
以下、複数のデータソースに問い合わせて、データが揃ったら画面表示するサンプルコード(Kotlin)。
import io.reactivex.Single
import io.reactivex.functions.BiFunction
import io.reactivex.functions.Function3
fun main(args: Array<String>) {
// 2つのデータを問い合わせて、揃ったら表示
Single.zip(hoge(1),
hoge(2),
BiFunction<Int, Int, Pair<Int, Int>> { n1, n2 -> Pair(n1, n2) })
.subscribe(
{ pair -> println("${pair.first}, ${pair.second}") }
)
// 3つのデータを問い合わせて、揃ったら表示
Single.zip(hoge(1),
hoge(2),
hoge(3),
Function3<Int, Int, Int, Triple<Int, Int, Int>> { n1, n2, n3 -> Triple(n1, n2, n3) })
.subscribe(
{ triple -> println("${triple.first}, ${triple.second}, ${triple.third}") }
)
}
// n秒待ってSingleでnを返す
// (APIやDBからの取得メソッドを想定)
fun hoge(n: Int): Single<Int> {
Thread.sleep(1000L * n);
return Single.just(n)
}
実行結果
1, 2
1, 2, 3
RxJavaだとTripleクラスがなくてダメかもしれない(?)。調べてないけど。
自分でクラス作るか、どっかのライブラリを使わないとダメかも。調べてないけど。
Rxはどうしても学習コストが高いけど、UI周りなんかの非同期処理をいい感じに書けるのがつよい。