RXKotlin 中的存储库模式连接结果

Posted

技术标签:

【中文标题】RXKotlin 中的存储库模式连接结果【英文标题】:Repository pattern concatenating results in RXKotlin 【发布时间】:2020-07-26 19:29:07 【问题描述】:

尝试使用离线优先的应用程序,我设法创建了一个工作存储库模式,它首先检查缓存,然后是数据库,最后是 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 调用失败,将自动导致没有结果。

【问题讨论】:

【参考方案1】:

也许你想要的是Maybe#switchIfEmpty(文档here)

然后你可以这样做:

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 
    
)

【讨论】:

这不是说我有 db results 或 api results 吗?如果 api 结果不为空,我想要两者的组合。

以上是关于RXKotlin 中的存储库模式连接结果的主要内容,如果未能解决你的问题,请参考以下文章

如何取消订阅RxKotlin / RxJava中的Flowable?

Rxkotlin 自动完成搜索

无法使用 RxKotlin 'observeOn' 主线程

RXKOTLIN/RXJAVA:使用 Observables 的套接字之间的通信

Spring Boot 存储库中的 API 与 DAO

使用 ServiceStack.ORMLite 的存储库模式中的事务