Предпочтительный способ обеспечить выполнение пары асинхронных задач - использовать coroutineScope
. Он будет приостановлен до тех пор, пока не будут завершены все дочерние задания, например, все вызовы на launch
или async
.
viewModelScope.launch {
withContext(dispatcherProvider.heavyTasks) {
val multipleIds = listOf(1, 2, 3, 4, 5, ..)
val content = arrayListOf<CustomObj>()
coroutineScope {
multipleIds.forEach { id ->
launch { // this will allow us to run multiple tasks in parallel
val apiResponse = api.get(id)
if (apiResponse.isSuccessful()) {
content.find { it.id == id }.enable = true
}
}
}
} // coroutineScope block will wait here until all child tasks are completed
liveData.postValue(content)
}
}
Если вам не нравится этот довольно неявный подход, вы также можете использовать более функциональный подход, сопоставляя ваши идентификаторы со списком Deferred
с использованием async
, а затем ожидайте их всех. Это также позволит вам запускать все задачи параллельно, но в итоге вы получите список результатов в правильном порядке.
viewModelScope.launch {
withContext(dispatcherProvider.heavyTasks) {
val multipleIds = listOf(1, 2, 3, 4, 5, ..)
val content = arrayListOf<CustomObj>()
val runningTasks = multipleIds.map { id ->
async { // this will allow us to run multiple tasks in parallel
val apiResponse = api.get(id)
id to apiResponse // associate id and response for later
}
}
val responses = runningTasks.awaitAll()
responses.forEach { (id, response) ->
if (response.isSuccessful()) {
content.find { it.id == id }.enable = true
}
}
liveData.postValue(content)
}
}