RxJava合并来自网络和数据库的数据

时间:2019-10-17 11:20:22

标签: android rx-java android-room

这是一个非常受欢迎的问题,可能会有各种各样的答案,
但我努力以正确的方式解决它。

我想要实现的目标:

  • 在没有错误的情况下,首先显示数据库中的缓存数据,然后更新 接收到来自网络的数据后。
  • 万一远程发生错误,请显示数据库中的数据, ,但还要了解已发生错误并显示“缓存的结果” (这是就我而言)

首先,我在存储库中有2种方法,分别从网络和数据库返回数据:

private fun getUsersFromRemote(): Single<List<User>>() =
    remote.getUsers()
        .flatMap {
            // saving fetched data to database
            db.userDao().insert(MakeDbMapper.mapFrom(it))
                .andThen(Single.just(it))
        }

private fun getUsersFromDatabase(): Flowable<List<User>>() =
    db.userDao.getUsers()
        .distincUntilChanged()

(为简化起见,此处跳过实体映射)

公共方法如下:

fun getUsers(): Flowable<List<User>> =
        Flowable.mergeDelayError(
            getUsersFromRemote()
                .toFlowable(),
            geUsersFromDb()
                .filter { it.isNotEmpty() })
            .distinctUntilChanged()
  • 在这样的实现中,由于以下原因,不会调用onError: mergeDelayError等待所有流终止。显然, 数据库的流不会这样做。
  • 在使用Flowable.merge()的情况下,它似乎可以正常工作-> 首先,我从数据库接收数据,然后是错误。 但是,这似乎不是正确的方法,因为有可能 从远程数据源fester接收到错误,然后从 数据库。它将导致流在获取之前终止 缓存的数据。
  • 在存储库中设置2种公共方法也许很有意义,

例如:

fun subscribeForUsers(): Flowable<List<User>> = db.usersDao.getUsers()

fun refreshUsersFromRemote(): Completable = 
    remote.getUsers()
        .flatMapCompletable {
            db.userDao().insert(it)
        }

在这种情况下,refreshUsersFromRemote()将让我处理远程错误,并在将新项目插入数据库后帮助将更新的用户发布到subscribeForUsers()

最后一种方法似乎对我有用,但我不确定它是否正确。
在这种情况下,我将不得不从Presentation层调用2个方法, 但是,我只想调用一个,并将所有合并逻辑的数据源封装在存储库中。

0 个答案:

没有答案