【问题标题】:Kotlin, RxJava2: compose and retryWhen after user interactionKotlin,RxJava2:用户交互后撰写和重试
【发布时间】:2019-03-13 01:00:55
【问题描述】:

在过去的两天里,我阅读了很多关于 rxJava retryWhen 运算符的信息。 Here, here, here 还有一些我忘了。

但不幸的是,我无法让它工作。 我想要实现的是,我进行了 API 调用。如果调用返回错误,我将通过重新加载按钮向用户显示 SnackBar。如果用户单击此按钮,我想重新订阅该链。

这是我的代码:

interface RetrofitApi {

@GET("/v1/loadMyData")
fun getMyData(): Single<Response<DataResponse>>
}

Response 来自于改造 2。我需要它来包装数据类以检查响应是否成功。

下一个乐趣是在 ViewModel 的存储库中调用:

override fun loadMyData(): Observable<Resource<DataResponse>> {
    return retrofitApi
            .getMyData()
            .compose(getRetryTransformer())
            .toObservable()
            .compose(getResponseTransformer())
}

Resource 是调用状态(SUCCESS、ERROR、LOADING)的另一个包装器。

最后是变压器:

private fun <Data> getRetryTransformer(): SingleTransformer<Response<Data>, Response<Data>> {
    return SingleTransformer { singleResponse ->
        singleResponse
                .onErrorReturn {
                    singleResponse.blockingGet()
                }
                .retryWhen { errors ->
                    errors.zipWith(retrySubject.toFlowable(BackpressureStrategy.LATEST),
                            BiFunction<Throwable, Boolean, Flowable<Throwable>> { throwable: Throwable, isRetryEnabled: Boolean ->
                                if (isRetryEnabled) {
                                    Flowable.just(null)
                                } else {
                                    Flowable.error(throwable)
                                }
                            })
                }
    }
}

重试主题:

private val retrySubject = PublishSubject.create<Boolean>()

当用户点击重试按钮时,我调用:

retrySubject.onNext(true)

现在的问题是,错误没有返回到 ViewModel 并且 SnackBar 永远不会显示。我也试过 onErrorResumeNext() 没有成功。整个 retryWhen/zipWith 部分似乎工作。因为在存储库中还有一些没有重试行为的 API 调用(还)并且那里显示了 SnackBar。这意味着,我在显示 SnackBar 的地方进行另一个调用 -> 按钮单击,并且重试转换按预期工作。

如果您需要更多信息,请随时询问!任何帮助表示赞赏!

【问题讨论】:

    标签: kotlin rx-java2 retrywhen


    【解决方案1】:

    奇怪,只要你做对了,它就会起作用。 我以某种方式过度阅读了我需要在 doOnError{...} 中设法显示我的 Snackbar。

    这是我的工作重试转换器:

    private fun <Data> getRetryTransformer(): SingleTransformer<Response<Data>, Response<Data>> {
        return SingleTransformer { singleResponse ->
            singleResponse
                    .doOnError {
                        errorEventSubject.onNext(it)
                    }
                    .retryWhen { errors ->
                        errors.zipWith(retrySubject.toFlowable(BackpressureStrategy.LATEST),
                                BiFunction<Throwable, Boolean, Flowable<Throwable>> { throwable: Throwable, isRetryEnabled: Boolean ->
                                    if (isRetryEnabled) {
                                        Flowable.just(throwable)
                                    } else {
                                        Flowable.error(throwable)
                                    }
                                })
                    }
        }
    }
    

    链条现在看起来像这样(我认为它很漂亮):

    override fun loadMyData(): Observable<Resource<DataResponse>> {
        return retrofitApi
                .getMyData()
                .compose(getRetryTransformer())
                .toObservable()
                .compose(getResponseTransformer())
    }
    

    我还需要将错误传播到我的 ViewModel 是第二个 PublishSubject:

    private val errorEventSubject = PublishSubject.create<Throwable>()
    

    在 ViewModel 中,我观察它的变化并显示 Snackbar。 而已。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-07
      • 2014-04-02
      • 2017-03-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多