2015-02-23 115 views
6

我想使用RxJava從Web服務(通過改造)加載數據。我也有一個以前的結果數據庫緩存。Android + RxJava - 從數據庫和網絡服務加載數據

讓我們假設我已經有可觀的每一項:

Observable<List<MyModel>> networkObservable = retrofitService.getModels(); 
Observable<List<MyModel>> dbObservable = database.getModels(); 

我想這兩個觀測合併成一個:

public class MyModelHelper { 
    public static Observable<List<MyModel>> getModels() { 
     // TODO: Help! 
    } 
} 

我想要的行爲是用戶能夠接收數據庫結果儘快可用,其次是restService服務結果(假設從db獲取比網絡呼叫快)

最好的,我可以拿出我自己的是:

public class MyModelHelper { 
    public static Observable<List<MyModel>> getModels() { 
     List<MyModel> emptyList = new LinkedList<>(); 

     // 'startWith' because combineLatest wont call back until all source observables emit something 
     Observable.combineLatest(dbObservable.startWith(emptyList), 
      networkObservable.startWith(emptyList), 
      new Func2<List<MyModel>, List<MyModel>, List<MyModel>>() { 
       @Override 
       public List<MyModel> call(List<MyModel> first, List<MyModel> second) { 
        return merge(first, second); 
      } 
     }); 
    } 
} 

這似乎有點哈克給我,我覺得這樣一個常見的情形,必須有一個更好的解決方案。

如果網絡observable發生錯誤,數據庫結果仍然會通過,這也會很好。我可以調用onErrorResumeNext()並返回dbObservable本身,但我仍然希望通知訂閱者發生了錯誤。

有什麼建議嗎?

回答

13

直接使用Observable.merge。它將幾個可觀察的流合併爲一個,所以如果數據庫發射更快,您將首先收到它。

public static Observable<List<MyModel>> getModels() { 
    return Observable.merge(dbObservable, networkObservable); 
} 
+1

好吧,這似乎幾乎是尷尬明顯!我使用'mergeDelayError()'來確保兩個可觀察對象都有機會返回。 非常感謝! – DanielGrech 2015-02-23 08:38:11

+5

除此之外,'mergeDelayError'將幫助您獲得所需的錯誤行爲。如果其中一個流出現錯誤,那麼在完成之前不會影響其他流,之後您可以使用任何錯誤操作符來處理錯誤。 – lopar 2015-02-23 08:39:34

+0

@lopar非常好的一點。同樣值得去看看merge和mergeDelayError的大理石圖來正確理解它http://reactivex.io/documentation/operators/merge.html – tomrozb 2015-02-28 07:01:09

相關問題