如何将具有差异的多个Observable合并回一个流?

时间:2018-04-11 18:22:44

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

我有这个问题。我正在尝试使用远程应用程序将本地数据库同步到我的Android应用程序中。我正在创建上传本地创建的新信息的逻辑,服务器以远程ID响应将其保存在服务器中。要归档这个,我使用的方法是获取一个对象数组,返回一个Observable,它为每个元素发出服务器的响应。 像这样。

val dailyEntries = App.db.dailyEntryDao().getDailyEntriesCreated()
            dailyEntries.sync(context) //Return an observable
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe({                        
                        val response = DailyEntry(it)//Creates a daily entry using 
                                                      the response from the server
                        thread {                                
                          App.db.dailyEntryDao().update(response)
                        }
                    }, {
                        it.printStackTrace()
                    }, {
                        uploadEnclosures()
                    })

如何在onSuccess中看到当前的observable调用另一种方法。它使用相同的逻辑并向前显示。

private fun uploadEnclosures() {
        thread {
            val enclosures = App.db.enclosureDao().getEnclosuresCreated()
            enclosures.sync(context)
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe({
                        val response = Enclosure(it)
                        thread {                                
                            App.db.enclosureDao().update(response)
                        }
                    }, {
                        it.printStackTrace()
                    }, {
                        uploadSmokeTest()
                    })
        }
    }

它继续所有表格。我们总是在当前Observable的onSuccess中执行下一个表的更新。它是这样完成的,因为我需要按特定顺序进行同步。

我的问题是,有没有办法将所有这些Observable合并为一个,以执行单个订阅并控制每个onNext情感?

感谢您的回答

1 个答案:

答案 0 :(得分:2)

是的,但是需要进行一些工作,您可以使用concat运算符来处理您的排序并按顺序将observables列表传递给订阅者然后订阅使用一个期望Any事件向下流动的观察者来使用它。

要严格控制类型安全,您可以使用通用接口标记可观察源类型,并使用实例检查来采取特定于事件类型的操作。

查看更多here

代码示例 -

fun concatCalls(): Observable<Any> {
    return Observable.concat(src1, src2, ...)
}

消费者看起来就像这样 -

concatCalls().subscribe(object: Subscriber<Any> {
    override fun onNext(o: Any) {
       when (o) {
           is Object1 -> // do handling for stuff emitted by src1
           is Object2 -> // do handling for stuff emitted by src2
           ....
           else // skip
    }
    ....
})