2017-09-01 28 views
0

为了使数据可以被脱机查看访问,我有一个数据层首先请求数据库中的数据,然后进行网络调用以从api获取数据(并存储它到数据库)。 F.e.说我要通过用户ID得到回收分数:RxJava 2 Debounce:当下一个可观察到的错误时如何忽略去抖动

数据层:

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

所以我的演讲者订阅存储库来getRecycleScoresByUserId。我正在使用去抖操作符来确保在api调用足够快的情况下,我不会在ui上设置两次返回的值,以防止ui闪烁。但是现在发生的情况是,当数据库成功返回一些recycleScores时,但由于某种原因,api请求响应的错误是,演示者中的订阅者仅接收到错误,而没有使用数据库中的值进行观察。

如何确保数据库的可观察性已被订户接收,并且在api调用返回错误时不会被去抖动?

回答

1

这可能不是最好的解决办法,但你可以在这部分过滤从您的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) } 
} 
+0

感谢,已经帮助。唯一的问题是我仍然需要找出如何处理错误/非200服务器响应的方式。任何提示呢? :) –

+1

我的一个想法是将你的回应包装成其他类型来表示成功和错误回应,然后你可以处理它。我在我的答案中添加了一个例子。希望它能帮助你。 – chandra