Делать несколько запросов API с различным телом запроса последовательно - PullRequest
0 голосов
/ 20 сентября 2018

Вариант использования: мне нужно отправить запрос на сервер с помощью Android-клиента (дооснащение).После того, как я получу свой первый ответ, мне нужно обновить значения отправляющего объекта (которые зависят от последнего полученного элемента) и отправить его снова, пока все данные не будут загружены.Я хочу знать, как я могу добиться этого с помощью Retrofit и RxJava (я не хочу использовать циклы и т. Д.)

РЕДАКТИРОВАТЬ: Дело в том, что я не знаю точное количество "плоских карт«потому что данные могут стать больше или меньше.У меня есть, скажем, 420000 записей, и для каждого запроса я загружаю 1000 данных

Ответы [ 2 ]

0 голосов
/ 20 сентября 2018

Вы можете использовать функцию генерации, которая содержит изменяемое состояние:

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()
        }
    })
0 голосов
/ 20 сентября 2018

Вы могли бы flatMap их, и использовать его ответ в следующем, используя параметр it, который является ответом предыдущего.

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

И в случае, если вы не 'не знаю, сколько у вас будет flatMap с, например, вы можете сделать это с помощью рекурсивной функции.

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