首页 > 解决方案 > RXKotlin 中的存储库模式连接结果

问题描述

尝试使用离线优先应用程序,我设法制作了一个工作存储库模式,它首先检查缓存,然后是数据库,最后是 api。我这样做:

private fun cachedTopics(): Maybe<List<Topic>> { ... }
private fun databaseTopics(): Maybe<List<Topic>> { ... }
private fun apiTopics(): Maybe<List<Topic>> { ... }

Maybe.concat(cachedTopics(), databaseTopics(), apiTopics())
     .firstOrError()
     .subscribeOn(scheduler)

现在,问题是我将部分数据保存在数据库中(不是所有主题)。如果用户连接到互联网并浏览,显示的数据将只是数据库中的数据。但这并不是用户应该访问的所有内容(如果他们连接到互联网)。我知道这是由于.firstOrError()电话。

但我想知道是否有一种方法可以连接数据库 + api 的不同结果(api 可能会失败并因此返回 0 结果)并返回一个 Single。

编辑

为了更清楚,我想要以下内容:

IF CACHE IS NOT EMPTY
   RETURN DISTINCT(DB + CACHE)
ELSE
   UPDATE CACHE WITH API RESULT
   RETURN DISTINCT(DB + API)

如果调用失败,API 调用将自动导致没有结果。

标签: androidkotlinrepository-patternrx-kotlin

解决方案


也许您想要的是(此处Maybe#switchIfEmpty的文档)

然后你可以做这样的事情:

class Repository() {

    fun topics() {
        return cachedTopics.switchIfEmpty(databaseOrApiTopics());
    }


    private fun databaseOrApiTopics() = databaseTopics().switchIfEmpty(apiTopicsWithUpdate())

    private fun apiTopicsWithUpdate() = apiTopics().doOnComplete {
        // update db
        // update cache?
    }
}

更新:如果你想将结果组合在一起,你可以通过Maybe.flatMap需要一个组合器的重载来做到这一点。就像是:

cachedTopics().switchIfEmpty(
    databaseTopics().flatMap { dbTopics ->
        apiTopics().doOnComplete { /* updateDb(it) */ }
            .map { apiTopics -> apiTopics + dbTopics }
    }
)

推荐阅读