为了使数据可供脱机查看,我有一个数据层首先从数据库请求数据,然后进行网络调用以从api获取数据(并将其存储到数据库)。 F.E.说我想通过用户ID获得回收分数:
数据层:
class RecycleScoreRepository{
fun getRecycleScoresByUserId(userId: Int): Observable<RecycleScores> {
return Observable.concatArray(
getRecycleScoresFromDb(userId),
getRecycleScoresFromApi(userId))}
}
object RepositoryManager {
...
fun getRecycleScoresByUserId(userId: Int): Observable<RecycleScores> {
return recycleScoreRepository.getRecycleScoresByUserId(userId)
//Drop DB data if we can fetch item fast enough from the API to avoid UI flickers
.debounce(400, TimeUnit.MILLISECONDS)} ...
主讲人:
RepositoryManager.getRecycleScoresByUserId(userId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
// do something on success
}, {
// do something on error
})
所以我的演示者正在订阅Repository以获取getRecycleScoresByUserId。我正在使用debounce运算符来确保api调用足够快以至于我没有在ui上设置两次返回值以防止ui闪烁。但现在发生的情况是,当数据库成功返回一些recycleScores但由于某种原因api请求响应时出现错误,即演示者中的订阅者只收到错误而不是来自数据库的值的observable。
如何确保订阅者收到数据库的可观察性,并且当api调用返回错误时不会被去抖?
答案 0 :(得分:2)
这可能不是最佳解决方案,但您可以在此部分中过滤api可观察响应中的错误
fun getRecycleScoresByUserId(userId: Int): Observable<RecycleScores> {
return Observable.concatArray(
getRecycleScoresFromDb(userId),
getRecycleScoresFromApi(userId)
.materialize()
.filter{ !it.isOnError }
.dematerialize<RecycleScores>()
)}
}
然后您的订阅者将继续获得结果。对于第二个问题,在收到错误时不要去抖动,我不知道如何实现这一点。
编辑: 要处理API响应中的错误,一个想法是将api响应包装到另一个类型,然后您可以正确处理它。例如:
sealed class RecycleResponse {
class OK(val score: RecycleScore) : RecycleResponse()
class NotOK(val error: Exception) : RecycleResponse()
}
然后你可以像这样使用它:
fun getRecycleScoresByUserId(userId: Int): Observable<RecycleResponse> {
return Observable.concatArray(
getRecycleScoresFromDb(userId),
getRecycleScoresFromApi(userId))
.map<RecycleResponse> { RecycleResponse.OK(it) }
.onErrorReturn { RecycleResponse.NotOK(it) }
}