用例: 我必须更新存储在本地数据库中的当前订单。这些步骤是:从后端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;
}
问题
你有一个想法如何在一个被动的方式来解决这个问题?是否有一个操作员允许将两个列表中的观察值分开。或者,也许我应该使用一个全局变量(似乎是一个坏主意),以保持信息哪些数据插入和更新?