RxJava 2 防抖:当下一个可观察对象发生错误时如何忽略防抖

4
为了使数据可以离线查看,我有一个数据层,首先从数据库请求数据,然后再进行网络调用以从API获取数据(并将其存储到数据库中)。 例如,如果我想按用户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
            })

我的Presenter正在订阅Repository以获取getRecycleScoresByUserId。我使用防抖运算符来确保在API调用足够快的情况下,不会将返回的值设置两次以防止UI闪烁。但是现在的问题是,当数据库成功返回一些recycleScores但由于某种原因api请求响应错误时,presenter中的订阅者仅收到错误而不是来自数据库的可观察值。

我如何确保订阅者接收到数据库的可观察值,并在api调用返回错误时不被防抖?

1个回答

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

谢谢,那已经有所帮助了。唯一的问题是我仍然需要找到一种处理错误/非200服务器响应的方法。对此有什么建议吗? :) - Rik van Velzen
1
我有一个想法,就是将您的响应包装成其他类型来表示成功和错误响应,然后您可以处理它。我在我的答案中添加了一个示例。希望能对您有所帮助。 - chandra
最好从响应中获取响应代码和错误。Retrofit Response<T> 很有帮助。 - Irfan Ul Haq

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接