Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/189.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rxjava在从数据库检索然后更新项目时创建一个循环_Java_Android_Kotlin - Fatal编程技术网

Rxjava在从数据库检索然后更新项目时创建一个循环

Rxjava在从数据库检索然后更新项目时创建一个循环,java,android,kotlin,Java,Android,Kotlin,我对rxjava有一个挑战,从数据库中检索一个项目有一个可观察的过程。我订阅了这个可观察的,并且在成功地从数据库检索到一个项目后,我更新了该项目。问题是,在更新项目之后,我获取项目的observable立即开始发出,并且再次调用update方法,因此创建了一个循环 示例代码 mOrderRepository.getOrder(orderId) .subscribeOn(mSchedulerProvider.io()) .observeOn(mSchedulerProvider.ui())

我对rxjava有一个挑战,从数据库中检索一个项目有一个可观察的过程。我订阅了这个可观察的,并且在成功地从数据库检索到一个项目后,我更新了该项目。问题是,在更新项目之后,我获取项目的observable立即开始发出,并且再次调用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);
});
如果
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);
    }
});