如何在不处理的情况下停止观察旧的 RxJava 响应状态?

How to stop observing old RxJava response statuses without dispose?

我有这样的案例。用户通过单击按钮启动请求链。然后他会制作两张照片上传。然而,在开始上传照片后,他可能 return 并重新开始处理。

我的 CompositeDisposable() 附加到 viewModel 它只会在 onCleared() 之后被清除。这就是为什么会出现奇怪的问题:用户可能会开始上传照片,返回,重新开始 并且将传送来自旧请求 的响应在上传新的之前!

我应该如何修改我所有的常规 RxJava 请求和 zip 运算符以仅处理新请求而不是旧请求。

同样,我不能在每个按钮事件之前调用 CompositeDisposable.dispose(),因为那样会终止上传过程。

我只需要处理可能的旧响应。

这是我的示例:

//called two times, for uploading
fun uploadPhoto(){
compositeDisposable.add(
            apiService.networkRequest(linkedHashMap, url)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribeWith(object: DisposableSingleObserver<retrofit2.Response<String>>() {
                        override fun onSuccess(t: retrofit2.Response<String>) {
                            // will provide result even if two new uploadPhoto() methods gets called
                            handleResponse(t)
                        }

                        override fun onError(e: Throwable) {

                        }
                    }))

}
}

fun handleResponse(response: retrofit2.Response<String>)
{
    responseList.add(response) //saves number of responses
    if(responseList.size == 2)
    {
        //calls new network request and creates a new logic. 
    }
}

问题是 handleResponse() 在 uploadPhoto() return 之前的结果

之后被调用

好的,如果我对你的情况理解正确的话,你想放弃第一次上传的响应并考虑第二次上传的响应,或者概括地说:忽略任何以前的响应并只考虑最新的响应。

如果是这样,那么一个简单的解决方案就是每次在开始新的上传之前检查 compositeDisposable。如果列表不为空,则丢弃所有内容并向其中添加新的一次性用品。

像这样:

fun uploadPhoto(){
   if(compositeDisposable.size() > 0){
       compositeDisposable.clear()
   }

   // ...
}

注意使用 compositeDisposable.clear() 而不是 .dispose()

关于您的跟进问题:

因此,调用 compositeDisposable.clear() 将处理列表中的每一项,更具体地说,这意味着工作线程将被中断,是的,在您的情况下,这意味着上传过程将终止。

如果你想继续上传,那么除了清除一次性物品外,你还得想出一个不同的机制。

我不确定你是否可以在 Rx 中做到这一点,但不涉及 Rx 的一个想法是让某种 uploadId,如生成的随机哈希,与每次上传相关联。此 ID 应提供给您的网络层,然后在响应中传回。

然后在 ViewModel 中,您将跟踪 currentUploadId,并且:

  • 每当用户执行新的上传时,使用新生成的 ID
  • 更新 currentUploadId
  • 每当收到 handleResponse(...) 时,您 检查 response.uploadIdcurrentUploadId,如果他们不这样做 匹配,那么您只需丢弃此响应。