我在使用rxjava时遇到了挑战,可以观察到从数据库中检索项目。我订阅了这个可观察的内容,并成功从数据库中检索了一个项目,然后更新了该项目。问题是在更新项目后立即发生,我观察到的获取项目开始发出,并且再次调用了update方法,从而创建了一个循环。
示例代码
mOrderRepository.getOrder(orderId)
.subscribeOn(mSchedulerProvider.io())
.observeOn(mSchedulerProvider.ui())
.subscribe((Order order) -> {
// i calculate amount due after payment then update this order
order.setAmountDue(amountDue);
mOrderRepository.updateOrder(order);
});
答案 0 :(得分:0)
如果getOrder(orderId)
返回一个Flowable<Order>
,它将在每次更新时一次又一次地收到订单,则应在一个单独的Single
的上下文中执行该命令,该更新可用于更新给定orderId
的项目。
public static final Object UNIT = new Object(); // avoid emitting `null`
public void updateOrder(final long orderId, final long amountDue) {
Single.fromCallable(() -> UNIT)
.subscribeOn(Schedulers.io())
.flatMap((ignored) -> getOrder(orderId).firstOrError()) // <-- convert Flowable to Single
.doOnSuccess(order -> {
order.setAmountDue(amountDue);
mOrderRepository.updateOrder(order);
}).subscribe();
}
或类似的东西。
答案 1 :(得分:0)
如果每次在数据库中更新Order
对象,并且每次在数据库中更新该Order
对象时,都会无限循环。缺少的逻辑应该回答以下问题:什么时候不应该更新对象?
一种解决方案,如@akarnokd所建议的,通过指定take(1)将检索限制在第一个发出的项目上:
mOrderRepository.getOrder(orderId)
.take(1)
.subscribeOn(mSchedulerProvider.io())
.observeOn(mSchedulerProvider.ui())
.subscribe((Order order) -> {
order.setAmountDue(amountDue);
mOrderRepository.updateOrder(order);
});
但是,在可以从另一个来源合法地多次更新订单的情况下,这可能不是您想要的逻辑。在这种情况下,比较接收到的订单的amountDue
(或其他相关属性)是否不同于更新金额可能是有意义的。如果是这样,请更新订单。
mOrderRepository.getOrder(orderId)
.subscribeOn(mSchedulerProvider.io())
.observeOn(mSchedulerProvider.ui())
.subscribe((Order order) -> {
// assuming `amountDue` has already been defined
if (!order.getAmoundDue().equals(amountDue)) {
order.setAmountDue(amountDue);
mOrderRepository.updateOrder(order);
}
});