2017-09-01 27 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