2016-12-02 33 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。使用该键执行适当的操作。