Как дождаться завершения всей асинхронной обработки?

У меня есть список запросов, которые я хочу выполнить, и я хочу дождаться их завершения, чтобы выполнить их. Я использую корутины котлина с повторением и асинхронностью, как показано ниже.

viewModelScope.launch(Dispatchers.IO) {
            repeat(serverAccountList.size) { 
                async { 
                    createHelloRequest(it)  // suspend function
                }
            }



            withContext(Dispatchers.Main) {
                _isLoading.value = false
            }
        }

Как я могу присоединиться к ним, чтобы продолжить свой код в главном диспетчере?


person james04    schedule 26.10.2019    source источник


Ответы (2)


Не используйте Dispatchers.IO для вызова приостанавливаемых (неблокирующих) функций. Весь ваш код может остаться в Main диспетчере. Кроме того, используйте от coroutineScope до launch столько подзадач, сколько вам нужно, и Kotlin обеспечит выполнение всех до завершения вызова coroutineScope.

Все вместе ваш код должен выглядеть так:

viewModelScope.launch {
    _isLoading.value = true
    coroutineScope {
        repeat(serverAccountList.size) {
            launch { createHelloRequest(it) }
        }
    }
    _isLoading.value = false
}
person Marko Topolnik    schedule 26.10.2019
comment
Почему мне не следует вызывать IO Dispatcher для приостанавливаемых функций? - person james04; 26.10.2019
comment
Настоящий вопрос в том, почему следует вам его использовать. Основная идея использования асинхронных сетевых API-интерфейсов, заключенных в приостанавливаемые функции, заключается в том, что вы избегаете тяжелых собственных потоков, которые ничего не делают, а ждут завершения операции блокировки. Диспетчер IO существует только как обходной путь для тех, кто застрял с блокирующим сетевым API. - person Marko Topolnik; 26.10.2019

Вам нужно вызвать await для асинхронного выполнения - например,

...

val stuff = async {...}
stuff.await()
...
person r2rek    schedule 26.10.2019