【问题标题】:Make multiple API requests with different request body sequentially按顺序发出多个具有不同请求主体的 API 请求
【发布时间】:2018-09-20 07:26:19
【问题描述】:

用例:我需要使用 android 客户端(改造)在服务器中发送一些请求。在我得到第一个答案后,我需要更新发送对象的值(取决于我得到的最后一项)并重新发送它,直到所有数据都下载完毕。我想知道如何使用 Retrofit 和 RxJava 实现这一点(我不想使用 while 循环等)

编辑: 问题是,我不知道“平面地图”的确切数量,因为数据可能会变大或变小。我有 420000 条记录,每个请求我下载 1000 条数据

【问题讨论】:

    标签: java android kotlin retrofit2 rx-java2


    【解决方案1】:

    你可以flatMap他们,并在下一个使用它的响应,通过使用it参数,这是前一个的响应。

    mathApi.multiplyByTwo(1)
        .flatMap {
            mathApi.multiplyByTwo(it)
        }.flatMap {
            mathApi.multiplyByTwo(it)
        }.subscribe {
            // here "it" will be 4 (1*2*2) 
        }
    

    如果您不知道最终将拥有多少个flatMaps,例如,您可以使用递归函数来完成。

    private fun multiplyByTwo(number: Int) {
        mathApi.multiplyByTwo(number).subscribe {
            if (it < Integer.MAX_VALUE) { // When you run out of data.
                multiplyByTwo(it)
            }
        }
    }
    

    【讨论】:

    • 他也可以使用协程。没有while循环等)
    • 问题是,我不知道“平面地图”的确切数量,因为数据可能会变大或变小。我有 420000 条记录,每个请求我下载 1000 条数据。
    • 在这种情况下,我只需编写一个递归函数。我将编辑我的回复。
    • 您是否尝试从您的 API 一次获取一个页面的数据?
    【解决方案2】:

    您可以使用保持可变状态的生成函数:

    data class ApiResponse(
        val nextPage: Int? = null
    )
    
    data class GeneratorState(
        var lastResponse: ApiResponse
    )
    
    fun makeApiCall(page: Int): ApiResponse {
        return ApiResponse(page + 1)
    }
    
    Flowable
        .generate(
            Callable { GeneratorState(makeApiCall(0)) },
            BiConsumer { state: GeneratorState, emitter: Emitter<ApiResponse> ->
                val latest = state.lastResponse
    
                if (latest.nextPage != null) {
                    val response = makeApiCall(latest.nextPage)
                    state.lastResponse = response
                    emitter.onNext(response)
                } else {
                    emitter.onComplete()
                }
            })
        .subscribe(object : FlowableSubscriber<ApiResponse> {
            var subscription: Subscription? = null
    
            override fun onSubscribe(s: Subscription) {
                subscription = s
                s.request(1)
            }
    
            override fun onNext(response: ApiResponse) {
                println("onNext :$response")
                if (response.nextPage != null && response.nextPage < 10) {
                    subscription?.request(1)
                } else {
                    subscription?.cancel()
                }
            }
    
            override fun onComplete() {
                println("Completed")
            }
    
            override fun onError(t: Throwable) {
                t.printStackTrace()
            }
        })
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-28
      • 1970-01-01
      • 2018-05-27
      • 2018-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多