Я пытаюсь выяснить, как лучше всего обрабатывать загрузку большого количества данных (до 1000 файлов / изображений, около 500 КБ каждое) с помощью retrofit2 и kotlin.
I Я пытался использовать сопрограммы с методомContext (), но при использовании enqueue он просто перебирает весь мой список файлов, ставя их в очередь сразу, что иногда приводит к проблемам, связанным с неправильной загрузкой некоторых файлов.
Если я использую модификацию execute (), загрузка файла обрабатывается синхронно, что также является трудной задачей и очень медленным в выполнении, но, безусловно, гораздо более надежным, поскольку при тестировании ему удавалось загружать все файлы каждый раз.
Как мне удалось получить лучшее из обоих миров, запустить этот асинхронный процесс с одновременной загрузкой нескольких файлов, но не так медленно, как синхронный метод?
Моя текущая реализация была примерно такой, пожалуйста, не забывайте что я все еще новичок в Kotlin и не использую все преимущества функционального программирования для работы Король со списками еще:
for(item in list) { ...
launch {
withContext(Dispatchers.Main) {
restAPIService.enqueue(object : RetryCallback<JsonObject>() {
override fun onResponse(
call: Call<JsonObject>,
response: Response<JsonObject>) {
if (response.isSuccessful) {
// handle response etc.
------------- РЕДАКТИРОВАТЬ -------------
После ответа и подсказка, как использовать .flatMap (), я теперь реализовал что-то вроде этого, и, кажется, работает:
myList
.asFlow()
.flatMapMerge(5) { frame ->
flow<Pair<Frame, Response<JsonObject>>> {
//init parameters to pass to the retrofit 2 call
val restAPIService = RestAPIService.RetrofitApi.retrofitService.uploadImages(
"Bearer $accessToken",
projectPart,
filePart,
folderNamePart,
metaDataPart
)
retrofitSuspendCall(restAPIService, frame, recording)
}
}
}
private suspend fun retrofitSuspendCall(
request: Call<JsonObject>, frame: Frame, recording: RecordingWithFrames): Response<JsonObject> = suspendCoroutine { continuation ->
request.enqueue(object : Callback<JsonObject> {
override fun onResponse(call: Call<JsonObject>, response: Response<JsonObject>) {
if (response.isSuccessful) {
continuation.resume(response)
}
//also handling onfailure
})