为了构建我的存储库,我从本地数据库和远程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
之类的该运算符的变体,结果是相同的,没有任何数据被检索。
一个有趣的注释是,在调试时,我注意到mQuakesLocalDataSource
和mQuakesRemoteDataSource
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<>());
}
结果相同,没有数据被检索。
答案 0 :(得分:1)
在Single
中返回空白列表不会使Single
为空白,因此first
将正确地停在第一项空白列表中,而不会调用远程源。您必须通过flatMap
决定是否要使用远程源而不是concat恢复该项目:
mQuakesLocalDataSource.getQuakes()
.flatMap(list -> {
if (list.isEmpty()) {
return mQuakesRemoteDataSource.getQuakes();
}
return Single.just(list);
})