【问题标题】:Android RxJava: Chaining two requests and doing some logic inbetweenAndroid RxJava:链接两个请求并在其间执行一些逻辑
【发布时间】:2018-06-15 04:39:42
【问题描述】:

您好,我正在尝试使用 flatmap 创建一系列网络请求,但不太了解如何执行此操作的过程。

我们的目标是这样做:

做networkRequest 1 一旦我从 networkRequestOne 获得结果,对该结果执行一些逻辑,然后执行下一个 networkRequestTwo 和调用 onSuccess 并从 networkRequestTwo 返回响应值。

当前代码:

delegator.requestOne(requestData)
                .flatMap ({  response ->
                    if(response.isSuccessful){
                        cookieStorage.saveSessionCookies(response.header(cookieStorage.COOKIE_HEADER_NAME)!!)
                    }
                    return delegator.requestTwo

                })
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeOn(Schedulers.io())
                .subscribe(object : SingleObserver<ResponseTwo>() {
                    @Override
                    fun onSubscribe(Disposable d) {
                    }

                    @Override
                    fun onSuccess(responseTwo :ResponseTwo) {
                        callback.onSuccess(responseTwo)
                    }

                    @Override
                    public void onError(Throwable e) {

                    }
                });

delegator.requestOne 和 delegator.requestTwo 都连接到返回 Single observable 的改造调用

【问题讨论】:

  • 我会将saveSessionCookies 放入doAfterSuccess(),因为这是一个副作用。但除此之外,当前的实现有什么问题?
  • 确实返回 delegator.requestTwo 的行突出显示了一个编译错误,说它排除了要返回的 Unit 不是可观察的?如果我删除 if 语句,它可以愉快地从 requestTwo 中返回另一个 observable
  • saveSessionCookie 需要在我调用下一个请求之前发生
  • 您实际上是在使用非本地退货。也就是说,要么完全删除return(最后一行将被解释为返回值),要么使用return@flatMap
  • 感谢您成功并摆脱了该错误

标签: android kotlin retrofit2 rx-java2 flatmap


【解决方案1】:

这有点奇怪,您需要在subscribe 方法中调用回调。如果您已经有 Rx,为什么还需要 cb?如果你返回一个Single 并在你实际订阅的地方运行你的回调代码会更清楚:

...
// don't forget to handle the `disposable`
doSmth(requestData)
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(
            { success -> /* here's your success callback code */},
            { error -> /* handle error here */}
    )
...

fun doSmth(requestData: RequestData): Single<ResponseTwo> = delegator.requestOne(requestData)
        .doOnSuccess(::updateCookies)
        // you can extract the data you need from the first request using `it`
        .flatMap { delegator.requestTwo() }

fun updateCookies(response: Response<ResponseOne>) {
    val cookie = response.header(cookieStorage.COOKIE_HEADER_NAME)!!
    cookieStorage.saveSessionCookies(cookie)
}

更新

如果你还需要callback

// don't forget to handle the `disposable`
delegator.requestOne(requestData)
        .doOnSuccess(::updateCookies)
        .flatMap { delegator.requestTwo() }
        .observeOn(AndroidSchedulers.mainThread())
        .subscribeOn(Schedulers.io())
        .subscribe(
                { success -> callback.onSuccess(success) },
                { error -> callback.onError(error) }
        )

fun updateCookies(response: Response<ResponseOne>) {
    if (response.isSuccessful) {
        val cookie = response.header(cookieStorage.COOKIE_HEADER_NAME)!!
        cookieStorage.saveSessionCookies(cookie)
    }
}

【讨论】:

  • cb 用于 UI 级别,而这些代码在演示者内部执行魔术。它需要来自 ui 的 callbck,因为此代码不驻留在 ui 类中
猜你喜欢
  • 1970-01-01
  • 2016-07-31
  • 1970-01-01
  • 2018-05-31
  • 2016-05-25
  • 1970-01-01
  • 1970-01-01
  • 2016-08-15
  • 2017-03-01
相关资源
最近更新 更多