RxJava 2 debounce:当下一个observable出错时如何忽略去抖动

时间:2017-09-01 12:25:49

标签: android repository-pattern rx-java2 debounce

为了使数据可供脱机查看,我有一个数据层首先从数据库请求数据,然后进行网络调用以从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调用返回错误时不会被去抖?

1 个答案:

答案 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) }
}