RxJava2 Single.Concat for repository pattern



我正在使用带有RxJava2的Room通过存储库模式原则实现我的数据层。

我有以下简单的代码,它决定从哪里选择数据。

@Override
    public Single<Team> getTeamById(int teamId) {
        return Single.
                concat(local.getTeamById(teamId),
                        remote.getTeamById(teamId)).
                filter(team -> team != null).
                firstOrError();
    }

这里的问题是,如果数据不可用,它不会转到 远程源 ,它会从第一个源(本地(返回错误。

android.arch.persistence.room.EmptyResultSetException: Query returned empty result set: select * from teams where id = ?

我应该如何指示 concat 放弃收到的任何错误并继续其连接?

只要您不确定是否可以从数据提供程序接收至少一个团队,您可能应该考虑使用 也许 而不是 Single。

您可以在此处查找定义:

单曲如其状态:

它总是发出一个值或错误通知

请改用"也许":或

可能有 0 或 1 个项目,或者由某些反应性发出错误信号 源

由于您的错误已经指出,从查询中提取结果时似乎存在问题。

正确处理结果提取,以便在尝试提取任何结果之前检查是否有结果。因此,也许将返回 0 或 1 项,并且在未找到团队时根本不会抛出任何错误。

你不能在 RxJava2 中传递 null。因此,每当本地存储库为空时,您就无法在单个存储库中返回 null。有一个关于处理空对象的问题:在 RxJava2 中处理空

同样在这里,您可以找到一篇文章,向您展示使用 RxJava2 的首选存储库模式实现:https://android.jlelse.eu/rxjava-2-single-concat-sample-for-repository-pattern-1873c456227a

如此简化 - 而不是从本地和远程存储库返回 null,而是传递某种"空"对象。这在您的业务逻辑中也很有用,允许您识别空数据集。

如果你想在

第一个源错误时继续(而不是完成为空(,你可以使用onErrorResumeNext而不是concat(我假设两个得到调用都返回Observable,根据需要进行调整(:

return local.getTeamById(teamId)
   .onErrorResumeNext(error -> {
       if (error instanceof EmptyResultSetException) {
           return remote.getTeamById(teamId));
       }
       return Observable.error(error);
   })
   .firstOrError();

我用Maybe来解决我的Rxjava2存储库模式问题。

在您的情况下,我将使用以下代码对其进行排序:

//you may need to rewrite your local.getTeamById method
protected Maybe<Team> getTeamById(int teamId) {
    Team team = localDataHelper.getTeamById(teamId);
    return team != null ? Maybe.just(team) : Maybe.empty();
}
@Override
public Single<Team> getTeamById(int teamId) {
    Maybe<Team> cacheObservable = local.getTeamById(teamId);
    Maybe<Team> apiCallObservable = remote.getTeamById(teamId).toMaybe();
    return Maybe.concat(cacheObservable, apiCallObservable)
            .toSingle();
}

最新更新