RxJava2 concat运算符未返回适当的流

时间:2018-08-05 19:11:47

标签: android repository rx-java2 android-room

为了构建我的存储库,我从本地数据库和远程API检索2个数据流。我试图通过使用mQuakesLocalDataSource运算符来仅在concat没有项目的情况下访问远程流。

@NonNull
@Override
public Single<List<Quake>> getQuakes(){
    return Single.concat(mQuakesLocalDataSource.getQuakes(),
                            mQuakesRemoteDataSource.getQuakes())
                              .first(dummyList);
}

我面临的问题是mQuakesRemoteDataSource为空时mQuakesLocalDataSource从不返回流,因此我没有任何数据结果。我已经单独测试了mQuakesRemoteDataSource,并且没有concat运算符,但似乎正在检索其适当的流。

为什么会这样?

mQuakesLocalDataSource是基于Room的,因此它应该发出它的流然后完成,因此本地源不可能像SQLbrite那样发出永无止境的流。

我尝试过使用concatArray之类的该运算符的变体,结果是相同的,没有任何数据被检索。

一个有趣的注释是,在调试时,我注意到mQuakesLocalDataSourcemQuakesRemoteDataSource get方法在传递给concat运算符之前都被触发。 first()行。 concat是否应该在有first运算符的情况下一个接一个地评估源(并过滤当前源)?

我还尝试过添加带有Predicate的过滤器,以便将数据缓存到本地数据源中,如下所示:

@NonNull
@Override
public Single<List<Quake>> getQuakes() {
    return Single.concat(mQuakesLocalDataSource.getQuakes(),
            mQuakesRemoteDataSource.getQuakes()).filter(new Predicate<List<Quake>>() {
        @Override
        public boolean test(List<Quake> quakes) throws Exception {
            boolean isValid = quakes != null && !quakes.isEmpty();

            // save items to local data source
            if (isValid) saveQuakes(quakes);

            return isValid;
        }
    }).first(new ArrayList<>());
}

结果相同,没有数据被检索。

1 个答案:

答案 0 :(得分:1)

Single中返回空白列表不会使Single为空白,因此first将正确地停在第一项空白列表中,而不会调用远程源。您必须通过flatMap决定是否要使用远程源而不是concat恢复该项目:

mQuakesLocalDataSource.getQuakes()
.flatMap(list -> {
    if (list.isEmpty()) {
        return mQuakesRemoteDataSource.getQuakes();
    }
    return Single.just(list);
})