Как обработать ошибку на нескольких цепочках Observable в RxJava? - PullRequest
0 голосов
/ 22 ноября 2018

Я занимаюсь разработкой приложения для Android с использованием Kotlin, RxJava и Retrofit.Я хочу отправить Http-запрос на сервер.

  1. PUT - опция обновления задания
  2. POST - запустить задание

После первого успешного запросаЗатем я отправляю второй запрос.Поэтому я использовал 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()
            })

1 Ответ

0 голосов
/ 22 ноября 2018

На самом деле, вы уже дали ответ.Ваш первый случай верен

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()
                    })
...