2016-11-13 44 views
3

我對rxJava相當陌生,嘗試自己的東西。我希望得到一些建議,如果我做對了。RxJava:如何等待所有訂閱完成?

用例:在我的應用程序的第一次運行中,成功登錄後,我必須下載並保存在本地數據庫中的多個字典供應用程序運行。用戶必須等到下載過程結束。

當前解決方案:我正在使用retrofit 2與rxjava適配器來獲取數據。我使用zip operator將所有觀察對象捆綁成一個。所有下載完成後,回調觸發並保存到數據庫中。

沒有什麼勝於一些代碼更好:

Observable<List<OrderType>> orderTypesObservable = backendService.getOrderTypes(); 
Observable<List<OrderStatus>> orderStatusObservable = mockBackendService.getOrderStatuses(); 
Observable<List<Priority>> prioritiesObservable = backendService.getPriorities(); 

return Observable.zip(orderTypesObservable, 
     orderStatusObservable, 
     prioritiesObservable, 
     (orderTypes, orderStatuses, priorities) -> { 
      orderTypeDao.deleteAll(); 
      orderTypeDao.insertInTx(orderTypes); 
      orderStatusDao.deleteAll(); 
      orderStatusDao.insertInTx(orderStatuses); 
      priorityDao.deleteAll(); 
      priorityDao.insertInTx(priorities); 

      return null; 
     }); 

問題

我應該使用ZIP運營商或者是有一個更好的適合我的原因是什麼?

這樣做似乎有點凌亂。這只是代碼的一部分,我目前有12個字典需要加載。有沒有辦法重構它?

我想盡快插入一個字典數據完成下載,並把它下載失敗重試機制。我怎樣才能做到這一點?

回答

2

我覺得在你的情況下最好使用Completable,因爲你只關心任務完成。

Completable getAndStoreOrderTypes = backendService.getOrderTypes() 
    .doOnNext(types -> *store to db*) 
    .toCompletable(); 

Completable getAndStoreOrderStatuses = backendService.getOrderStatuses() 
    .doOnNext(statuses -> *store to db*) 
    .toCompletable(); 

Completable getAndStoreOrderPriorities = backendService.getOrderPriorities() 
    .doOnNext(priorities -> *store to db*) 
    .toCompletable(); 

return Completable.merge(getAndStoreOrderTypes, 
         getAndStoreOrderStatuses, 
         getAndStoreOrderPriorities); 

如果您需要串行執行 - 使用Completable.concat()代替merge()

重試機制,如果下載失敗

使用起來得心應手retry()操作

1

這是不好的,扔空值對象到的Rx流(在壓縮您返回null,它是壞的)。 儘量不要這樣做。

你的情況,你有1 API調用和2個行動來響應保存到數據庫中,這樣你就可以創建flatMap鏈。

它看起來像:

backendService.getOrderTypes() 
.doOnNext(savingToDatabaseLogic) 
.flatMap(data -> mockBackendService.getOrderStatuses()) 
.doOnNext(...) 
.flatMap(data -> backendService.getPriorities()) 
.doOnNext(...) 

,如果你想在錯誤情況作出反應,特別是可觀察的,你可以添加onErrorResumeNext(exception-> Observable.empty())和鏈將繼續即使事情發生

此外,您還可以像BaseDao創造的東西,它可以保存任何DAO對象。