我正在尝试理解switchIfEmpty运算符的逻辑。我将非常感谢你的每一个解释。我有一个本地数据库(房间(和远程服务器。我的目标是用switchIfEmpty实现逻辑,以检查本地DB中是否有数据可以接受,以及本地DB是否为空,可以从远程调用。这个过程从我订阅Observable的活动开始:
private fun subscribeOnDataChanges() = with(viewModel) {
requestNextPage()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
filmsAdapter.addItems(it)
}, {
errorEvent.value = ERROR_MSG
it.printStackTrace()
}).addTo(autoDisposable)
}
然后视图模型中的方法:
fun requestNextPage(): Observable<List<Film>> {
return requestPageOfFilms()
}
private fun requestPageOfFilms(): Observable<List<Film>> =
interactor.requestPageOfFilmsFromDataSource()
最后,在交互程序中使用switchIfEmpty的方法:
fun requestPageOfFilmsFromDataSource(): Observable<List<Film>> {
return repo.getPageOfFilmsInCategory(category).filter { it.isNotEmpty() }.switchIfEmpty(
getFromRemote(category)
)
}
private fun getFromRemote(category: String): Observable<List<Film>> {
return convertSingleApiToObservableDtoList(
retrofitService.getFilms(
category, API.KEY, "ru-RU", NEXT_PAGE
)
)
}
我无法理解接下来的事情:
- 为什么当本地数据库(repo(不为空时,会调用getFromRemote((
- 如果本地数据库为空,为什么不执行方法getFromRemote((中的网络调用?没关系,我订阅了活动吗?因为如果我在switchIfEmpty((中添加订阅,就会执行网络调用
回答您的问题:
- 为什么当本地数据库(repo(不为空时,会调用getFromRemote((
因为此函数 因为上游尚未发出或完成值。您正在将空 如果你希望上游有一个健谈的结果,而只关心最新的结果,那么使用convertSingleApiToObservableDtoList()
是在装配时间而不是订阅时间List
与空Observable
合并(https://reactivex.io/documentation/operators/defaultifempty.html)flatMap
甚至switchMap
操作符是解决问题的更好方法,比如:fun requestPageOfFilmsFromDataSource(): Observable<List<Film>> {
return repo.getPageOfFilmsInCategory(category)
.flatMap { films ->
if (films.isNotEmpty()) {
Observable.just(films)
} else getFromRemote(category)
}
}