我正在使用Kotlin,RxJava和Retrofit开发一个Android应用程序。 我想将Http请求发送到服务器。
第一个请求成功后,我发送第二个请求。 所以我用了concatMap。
val updateJob = restService.updateJob(token, job.id, options) // PUT
val runJob = restService.runJob(token, job.id) // POST
updateJob.concatMap { runJob }
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ job ->
Log.d(TAG, "runJob - success: $job")
}, {
Log.e(TAG, "runJob - failed: ${it.message}")
it.printStackTrace()
})
如果第一个请求失败,我想取消。 我该怎么办?
这是可能的代码。 但是...这段代码是...我认为这很丑... 请问有没有很酷的代码?
disposable.add(
restService.updateJob(token, job.id, options) // PUT
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ job ->
Log.d(TAG, "updateJob - success")
restService.runJob(token, job.id) // POST
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ job ->
Log.d(TAG, "runJob - success")
}, {
Log.e(TAG, "runJob - failed: ${it.message}")
it.printStackTrace()
})
}, {
Log.e(TAG, "updateJob - failed: ${it.message}")
it.printStackTrace()
})
)
我还有一个问题。 我有工作清单。 我想做同样的事情。 即使某些作业失败,我也想继续下一个作业。 我考虑了“ onErrorResumeNext,onErrorReturn,doOnError”。 但是它们不是解决方案。 我该怎么办?
Observable.fromIterable(jobs)
.concatMap { job ->
val updateJob = restService.updateJob(token, job.id, options)
val printJob = restService.printJob(token, job.id)
updateJob.concatMap { printJob }
}
.window(1) // I thought "window" can be the solution. But it doesn't work.
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ job ->
Log.d(TAG, "runJobs - success")
}, {
Log.e(TAG, "runJobs - failed: ${it.message}")
it.printStackTrace()
})
答案 0 :(得分:1)
实际上,您已经给出了答案。 您的第一种情况是正确的
val updateJob = restService.updateJob(token, job.id, options) // PUT
val runJob = restService.runJob(token, job.id) // POST
updateJob.concatMap { runJob }
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ job ->
Log.d(TAG, "runJob - success: $job")
}, {
Log.e(TAG, "runJob - failed: ${it.message}")
it.printStackTrace()
})
因此,在这种情况下,如果updateJob
请求失败,则流将移至error stream
,而runJob
请求将永远不会被调用。
runJob
仅在updateJob
成功时才会被调用。
在updateJob
成功后,如果runJob
失败,那么也会调用error stream
。
您不需要第二种解决方案。
对于第二个问题,onErrorResumeNext
应该起作用。返回任何哑数值,并在onNext
Observable.fromIterable(jobs)
.concatMap { job -> restService.updateJob(token, job.id, options).onErrorResumeNext(Flowable.just(/*Send any dummy value*/)) }
.contcatMap { job -> restService.printJob(token, job.id).onErrorResumeNext{Flowable.just(/*Send any dummy value*/)} }
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ job ->
/*If dummy value received....handle it gracefully*/
Log.d(TAG, "runJobs - success")
}, {
Log.e(TAG, "runJobs - failed: ${it.message}")
it.printStackTrace()
})