【问题标题】:How to send a custom throwable down through flatmap in RxJava on Android?如何在 Android 上的 RxJava 中通过 flatmap 发送自定义的 throwable?
【发布时间】:2019-06-13 01:36:15
【问题描述】:

所以我使用 flatMap 和 RxJava 来链接一些返回 Singles 的 API 调用,并且想知道如何根据我自己的条件将自定义 throwable 传递给 flatmap 方法中的 subscribe 方法。

这是一个使用 MVVM 和 RxJava2/RxAndroid 进行数据操作的 Android Kotlin 应用程序。我正在尝试使用 flatmap 方法将一堆返回 Singles 的 API 调用链接在一起。每次,我想在上一个 API 方法之后调用一个新的 API 方法,我想检查上一个调用的响应是否成功。如果上一个调用的响应成功,我只需调用 flatmap 中的下一个 API 方法,一切都很好,但如果上一个调用的响应不成功,我想传递一个自定义的 throwable,告诉我操作的位置和原因成功。现在在响应不成功的情况下,我传递了一个带有空值的 Single,但这只是在订阅时给了我一个空指针,这不是很有帮助。

dataManager.apiCall1(dataManager.sessionId!!)
            .subscribeOn(schedulerProvider.io())
            .observeOn(schedulerProvider.ui())
            .flatMap{apiCall1Response ->
                if (apiCall1Response.isSuccessful && apiCall1Response.body() != null) {
                    // First api call was successful, execute api call 2.
                    return@flatMap dataManager.apiCall2(apiCall1Response.importantVal)
                } else {
                    // First api call failed 
                    Single.just(null)
                }
            }.flatMap{apiCall2Response ->
                if (apiCall2Response != null && apiCall2Response.isSuccessful && apiCall2Response.body() != null) {
                    // Second api call was successful, execute api call 3.
                    return@flatMap dataManager.apiCall3(apiCall2Response.importantVal)
                } else {
                    // Second api call failed
                    Single.just(null)
                }
            }.subscribe({apiCall3Response ->
                if (apiCall3Response != null && apiCall3Response.body() != null) {
                   // Success!
                   navigator!!.successful(response)
                } else {
                   // Third api call failed, handle error
                   navigator!!.handleError(Throwable("Api call 3 failed."))
                }
            }, {throwable ->
                // Failure, this is where I want to receive a custom throwable 
                // in case one of the responses were unsuccessful.
                navigator!!.handleError(throwable)
            })

我希望可抛出的消息类似于“apiCall1”失败,但 apiCall1 失败时的可抛出消息只是 NullPointer,因为我传递了 Single.just(null)。

【问题讨论】:

    标签: android mvvm kotlin rx-java2 rx-android


    【解决方案1】:

    使用Single.error() 代替Single.just(null)。 例如:Single.error<TypeHere>(RuntimeException("First api call failed"))

    【讨论】:

      【解决方案2】:

      为了最易读的代码,定义一个像这样的扩展函数

      private fun <T> Single<Response<T>>.decorateWithErrorHandling(): Single<T> {
          return this
                  .onErrorResumeNext { throwable ->
                      // Map network layer exceptions, e.g. IOException to your specific "domain level" exceptions
                      Single.error(mapNetworkErrorToSpecificThrowable(throwable))
                  }
                  .flatMap { response ->
                      if (response.isSuccessful) {
                          Single.just(response.body())
                      } else {
                          Single.error(convertToSpecificThrowable(response))
                      }
                  }
      }
      

      像这样使用它:

      apiCall1()
          .composeWithErrorHandling().flatMap { result1 -> apiCall2(result1) }
          .composeWithErrorHandling().flatMap { result2 -> apiCall3(result2) }
      

      等等

      【讨论】:

        【解决方案3】:

        使用此代码

        从 flatMap 抛出 NullPointerException

        并通过以下方式捕获错误 .onErrorReturn(throwable -> {//你的工作在这里})

        @Carson J.

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-08-28
          相关资源
          最近更新 更多