runBlocking
ожидает завершения всех функций приостановки, но поскольку concurrentCrawl
в основном просто запускает новые задания в новых потоках с GlobalScope.async
currentCrawl
, и, следовательно, runBlocking
выполняется после того, как все задания были запущены, а не после того, как все эти работы завершены.
Вам нужно подождать, пока все задания, начинающиеся с GlobalScope.async
, завершатся следующим образом:
suspend fun concurrentCrawl() {
cities.map { loc ->
1.rangeTo(10).map { start ->
GlobalScope.async {
val rests = scrapYelp.scrap(loc, start * 10)
restaurantsRepository.saveAll(rests)
}
}.awaitAll()
}
}
Если вы хотите дождаться окончания concurrentCrawl()
за пределами concurrentCrawl()
, вы должны передать результаты Deferred
в вызывающую функцию, как в следующем примере. В этом случае ключевое слово suspend
можно удалить из concurrentCrawl()
.
fun concurrentCrawl(): List<Deferred<Unit>> {
return cities.map { loc ->
1.rangeTo(10).map { start ->
GlobalScope.async {
println("hallo world $start")
}
}
}.flatten()
}
runBlocking {
concurrentCrawl().awaitAll()
}
Как уже упоминалось в комментариях: в этом случае метод async
не возвращает никакого значения, поэтому вместо него лучше использовать запуск:
fun concurrentCrawl(): List<Job> {
return cities.map { loc ->
1.rangeTo(10).map { start ->
GlobalScope.launch {
println("hallo world $start")
}
}
}.flatten()
}
runBlocking {
concurrentCrawl().joinAll()
}