Chain Completable 和单个 RxJava + Retrofit

Chain Completable and a Single RxJava + Retrofit

在我的存储库中,我有两个 API 调用应该按顺序完成。

  1. 第一个 API 调用 returns 可完成 -> 如果此 API 调用失败,我们不应继续进行,如果成功,我们应继续第二个 API打电话
  2. 第二次 API 调用 returns 单次 -> 如果此 API 调用失败,我们不应该抛出错误,我们仍然可以继续

我怎样才能做到这一点?

我现在正在做的是使用来自 repo 的单独调用。

存储库:

override fun activate(id: String): Completable {
    return api1.post(Body(id = id))
        .subscribeOn(schedulerProvider.io())
}

override fun fetchAd(id: String): Single<SummaryAd> {
    return api2.getAd(adId)
        .subscribeOn(schedulerProvider.io())
        .map { it.toSummaryAd() }
}

视图模型:

private fun activate(id: String) {
    repository.activate(id)
        .subscribeOn(schedulerProvider.io())
        .observeOn(schedulerProvider.ui())
        .subscribe(
            { // if it is successful, let's continue
                fetchAd(id)
            },
            { // otherwise fail
                _state.value = State.ErrorActivation
            }
        ).also { compositeDisposable.add(it) }
}

private fun fetchAd(id: String) {
    repo.fetchAd(id)
        .subscribeOn(schedulerProvider.io())
        .observeOn(schedulerProvider.ui())
        .subscribe(
            { // success
                _state.value = State.ActivationSuccess(it)
            },
            {
                // even though the call has failed, the activation is succeeded, so we still can proceed but with empty data
                _state.value = State.ActivationSuccess(SummaryAd())
            }
        ).also { compositeDisposable.add(it) }
}

基本上我最终想要的是在我的 viewModel 中有一个函数并让存储库顺序调用它们并且只在第一个 API 调用失败时抛出错误。

使用andThen

activate(id)
.andThen(
    fetchAd(id)
    .onErrorReturnItem(SummaryAd())
)

这大致就是您所需要的,具体取决于您对 _state 的实现,您可能也不需要在 UI 线程上设置它的值。

 compositeDisposable.add(
            repository.activate(id)
                .subscribeOn(schedulerProvider.io())
                .andThen{
                    repo.fetchAd(id)
                        .subscribeOn(Schedulers.io())
                        .onErrorReturnItem { SummaryAd() }
                }
                .observeOn(schedulerProvider.ui())
                .subscribe(
                    {
                        _state.value = State.ActivationSuccess(it)
                    },
                    {
                        // this will be executed only, in case of activate request failure, as fetch add can never fail due to onErrorReturn
                        _state.value = State.ErrorActivation
                    }
                )
        )