Rxjava在从数据库检索然后更新项目时创建一个循环
我对rxjava有一个挑战,从数据库中检索一个项目有一个可观察的过程。我订阅了这个可观察的,并且在成功地从数据库检索到一个项目后,我更新了该项目。问题是,在更新项目之后,我获取项目的observable立即开始发出,并且再次调用update方法,因此创建了一个循环 示例代码Rxjava在从数据库检索然后更新项目时创建一个循环,java,android,kotlin,Java,Android,Kotlin,我对rxjava有一个挑战,从数据库中检索一个项目有一个可观察的过程。我订阅了这个可观察的,并且在成功地从数据库检索到一个项目后,我更新了该项目。问题是,在更新项目之后,我获取项目的observable立即开始发出,并且再次调用update方法,因此创建了一个循环 示例代码 mOrderRepository.getOrder(orderId) .subscribeOn(mSchedulerProvider.io()) .observeOn(mSchedulerProvider.ui())
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);
});
如果getOrder(orderId)
返回一个Flowable
,它将在每次更新时一次又一次地接收订单,那么这应该在一个单独的单个
的上下文中执行,该单个可用于为给定的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();
}
公共静态最终对象单元=新对象();//避免发出“null”`
public void updateOrder(最终长订单ID、最终长订单到期日){
单个.fromCallable(()->单位)
.subscribeOn(Schedulers.io())
.flatMap((忽略)->getOrder(orderId).firstOrError())//{
订单.设置到期日(到期日);
更新顺序(order);
}).subscribe();
}
或者类似的东西。如果每次数据库中更新一个
Order
对象,并且每次在数据库中更新该Order
对象,它将无限期地循环。缺少的逻辑应该回答以下问题:什么时候不更新对象
正如@akarnokd所建议的,一种解决方案是通过指定take(1)将检索限制到第一个发出的项:
但是,在可以合法地从其他来源多次更新订单的场景中,这可能不是您想要的逻辑。在这种情况下,比较收到的订单的到期金额
(或任何其他相关属性)是否与更新金额不同可能是有意义的。如果是,请更新订单
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);
}
});
那么为什么抓取数据会触发写入呢?再次触发抓取数据的是写入数据(即更新该项)。如果它应该是一项,请在
getOne()
@akarnokd之后使用take(1)
,我会添加该项,但我仍然会面临这个问题,因为在获取该项后,我会更新它,getOne observable再次被触发,然后我得到相同的项更新它,getOne observable被触发。我希望你现在能看到我的问题如果你想更新条目为什么不直接输入?所以orderepo.updateOne(id)。如果您尝试在fetch或任何其他操作之后更新条目,请尝试在将对象写入db之前应用您对该对象的更改(但不要在rx流中对其进行变异)。
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);
}
});