Rxでzipを使って3ソースから情報取得するKotlinコード

アプリの画面表示処理などで、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周りなんかの非同期処理をいい感じに書けるのがつよい。

スポンサーリンク