2016-12-02 34 views
1

用例: 我必須更新存儲在本地數據庫中的當前訂單。這些步驟是:從後端RxJava:拆分可觀察到兩個列表

  1. 下載數據(〜800項)
  2. 檢查本地數據庫已經包含項目。後端球員使用一個字符串作爲主鍵。
  3. 如果該項目不在數據庫中,請添加它。
  4. 如果項目在數據庫中,請更新它。

我的第一個解決方案很容易做到。只需調用後端併爲每個項目創建兩個數據庫查詢。首先檢查它是否已經存在,然後添加或更新它。

正如你可能想象的那樣緩慢。每次更新大約17.5秒。

第二種解決方案:將數據庫數據緩存到列表中,而不是每次在ArrayList中搜索時查詢數據庫。這導致更新時間下降到16.5秒。我使用defer來創建數據庫調用ObservablecombineLatest以獲取結果。

當前解決方案: 瓶頸當然是數據更新。我正在使用的orm庫啓用批量更新。所以我必須創建兩個列表:DataToUpdateDataToInsert

當前的解決方案運行約5.3秒。我對時間很滿意,但對這種做法的非反應性方式感到不滿。

Observable<List<OrderDto>> getAllOrdersObservable = backendService.getAllOrders(); 

ordersDisposable = Observable.combineLatest(getStoredOrder(), getAllOrdersObservable, this::insertOrUpdateOrders) 
     .subscribeOn(Schedulers.io()) 
     .observeOn(AndroidSchedulers.mainThread()) 
     .doOnComplete(() -> { 
      Log.d(TAG, "Duration: " + (System.currentTimeMillis() - start) + " ms"); 
      showSyncButton(); 
      notifyListenersDataDownloaded(); 
     }) 
     .subscribe(); 


private Observable<List<Order>> getStoredOrder() { 
    return Observable.defer(() -> { 
     Log.d(TAG, "Started loading orders from database"); 
     Observable<List<Order>> just = Observable.just(orderDao.loadAll()); 
     Log.d(TAG, "Ended loading orders from database"); 
     return just; 
    }); 
} 

private List<Order> insertOrUpdateOrders(List<Order> orders, List<OrderDto> orderDtos) { 
    List<Order> ordersToInsert = new LinkedList<>(); 
    List<Order> ordersToUpdate = new LinkedList<>(); 

    for (OrderDto orderDto : orderDtos) { 
     Order order = getOrderByOrderNumber(orders, orderDto.getNumber()); 
     if (order != null) { 
      dtoToEntityTransformer.updateFields(orderDto, order); 
      ordersToUpdate.add(order); 
     } else { 
      order = dtoToEntityTransformer.transformToEntity(orderDto); 
      ordersToInsert.add(order); 
     } 
    } 

    orderDao.insertInTx(ordersToInsert); 
    orderDao.updateInTx(ordersToUpdate); 

    return orders; 
} 

問題

你有一個想法如何在一個被動的方式來解決這個問題?是否有一個操作員允許將兩個列表中的觀察值分開。或者,也許我應該使用一個全局變量(似乎是一個壞主意),以保持信息哪些數據插入和更新?

回答

1

使用groupBy,其中關鍵在於它是否是更新/插入操作;你將得到一個包含密鑰的GroupedObservable。使用該鍵執行適當的操作。