用例: 我必須更新存儲在本地數據庫中的當前訂單。這些步驟是:從後端RxJava:拆分可觀察到兩個列表
- 下載數據(〜800項)
- 檢查本地數據庫已經包含項目。後端球員使用一個字符串作爲主鍵。
- 如果該項目不在數據庫中,請添加它。
- 如果項目在數據庫中,請更新它。
我的第一個解決方案很容易做到。只需調用後端併爲每個項目創建兩個數據庫查詢。首先檢查它是否已經存在,然後添加或更新它。
正如你可能想象的那樣緩慢。每次更新大約17.5秒。
第二種解決方案:將數據庫數據緩存到列表中,而不是每次在ArrayList中搜索時查詢數據庫。這導致更新時間下降到16.5秒。我使用defer
來創建數據庫調用Observable
和combineLatest
以獲取結果。
當前解決方案: 瓶頸當然是數據更新。我正在使用的orm庫啓用批量更新。所以我必須創建兩個列表:DataToUpdate和DataToInsert。
當前的解決方案運行約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;
}
問題
你有一個想法如何在一個被動的方式來解決這個問題?是否有一個操作員允許將兩個列表中的觀察值分開。或者,也許我應該使用一個全局變量(似乎是一個壞主意),以保持信息哪些數據插入和更新?