У меня есть ситуация, когда мне нужно отправить неопределенное количество сетевых вызовов, известных только во время выполнения.Каждый звонок возвращает список.Поскольку каждый возвращается, мне нужно объединить эти списки в один объединенный список.Для этого я использую сопрограммы.
Проблема, с которой я сталкиваюсь, связана с тем, что я не знаю, сколько сетевых вызовов потребуется приложению.Чтобы решить эту проблему, я использую цикл для перебора списка вызовов во время выполнения:
private suspend fun fetchData(params: List<Interval>): List<Item> {
val smallLists = mutableListOf<Deferred<List<Item>>>()
val merged = mutableListOf<List<Item>>()
for (index in 0 until params.size) {
val param = params[index]
// loop stop iterating after this call is dispatched
smallLists[index] = CoroutineScope(Dispatchers.IO).async {
fetchList(param)
}
}
for (index in 0 until smallLists.size) {
merged[index] = smallLists[index].await()
}
return merged.flatMap { it.toList() }
}
private fun fetchList(param: Interval) : List<Item> {
return dataSource.fetchData(param)
}
В этом коде происходит то, что он входит в первый цикл.Список params
правильный.Он отправляет первый запрос, и этот запрос возвращает (я могу видеть это через прокси Чарльза).
Но здесь все просто умирает.Приложение ничего не делает с ответом сети, и цикл завершается (т. Е. Второй итерации цикла нет).
Я знаю, что все остальное не повреждено, потому что у меня есть альтернативная версия, которая не включает в себя цикл.Он просто выполняет два запроса, ожидает их результатов и возвращает объединенный список.Он работает нормально, за исключением того, что он не будет обрабатывать динамическую ситуацию во время выполнения:
private suspend fun fetchData(params: List<Interval>): List<Item> {
val list1 = CoroutineScope(Dispatchers.IO).async {
fetchList(params[0])
}
val list2 = CoroutineScope(Dispatchers.IO).async {
fetchList(params[1])
}
return list1.await() + list2.await()
}
Возможно, здесь простое решение, но я его не вижу.Любая помощь приветствуется.