结合多个可观察量的结果

时间:2017-10-18 21:35:24

标签: android kotlin rx-java observable reactive-programming

我试图实现这样的目标: - 进行两个不同的API调用,并将结果合并到一个列表中。每个调用的结果是一个HashMap,我有一个函数将它转换为一个列表。我现在要做的就是将这些列表合并为一个,但我遇到了困难。

这就是我的Retrofit服务的样子:

@GET("data/price?fsym=ETH")
fun getETHRates(@Query("tsyms") tsyms : String) : Single<HashMap<String, 
Double>>

@GET("data/price?fsym=BTC")
fun getBTCRates(@Query("tsyms") tsyms: String) : Single<HashMap<String, Double>>

我已经能够单独拨打电话并将结果转换成一个列表(如果可以做得更好,请纠正我),如下所示:

  val btcRates: Single<List<Currency>> = cryptoApi.getBTCRates(countries)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .flatMap { result: HashMap<String, Double> ->
                return@flatMap Single.just(createCurrencyObjects
                ("BTC",
                        result))
            }

    val ethRates: Single<List<Currency>> = cryptoApi.getETHRates(countries)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .flatMap { result: HashMap<String, Double> ->
                return@flatMap Single.just(createCurrencyObjects("ETH", result))
            }

这是将结果转换为列表的函数:

    fun createCurrencyObjects(from: String, map: HashMap<String, Double>): List<Currency> {
    val list = ArrayList<Currency>(0)

    for (key in map.keys) {
        val amount: Double? = map.get(key)
        list.add(Currency(0, from, key, amount!!))
    }

    return list;
}

我现在要做的是合并两个调用的列表,然后将其保存到数据库中。如何与RxJava进行此组合?

我尝试过这样的事情,但我不断收到错误消息:

        val apiCall: Disposable = Observable.concat(ethRates, btcRates)
            .subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread())
            .doOnNext { values: List<Currency> ->
                run {
                    App.database?.currencyDao()?.insertAllCurrencies(values)
                }
            }
            .doOnError { e -> e.printStackTrace() }
            .subscribe();

2 个答案:

答案 0 :(得分:1)

使用zip运算符,您可以合并Single的结果并应用返回列表的转换函数

Single.zip(
            rates1,
            rates2,
            BiFunction<List<Currency>, List<Currency>, List<Currency>> { x, y ->
                // return your list
            }
    ).doOnSuccess { list -> // save your data }
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())

答案 1 :(得分:0)

gyosida的答案是正确的。这是另一个显示Zip的一般用法的例子:

    val single1 = Single.just(mutableListOf("one", "two", "three"))
    val single2 = Single.just(mutableListOf("four", "five", "six"))

    val single = Single.zip(single1, single2, BiFunction {
        a: MutableList<String>, b: MutableList<String> ->
            a.addAll(b)
            return@BiFunction a
    }) 

快乐的编码!