У меня есть коллекция, и я хочу асинхронно выполнить некоторые операции над всеми ее элементами в Kotlin.
Я могу сделать это легко с помощью двух операций с картой:
suspend fun collectionAsync() = coroutineScope {
val list = listOf("one", "two", "three")
list.map { async { callRemoteService(it) } }.map { it.await() }.forEach { println(it) }
}
suspend fun callRemoteService(input: String): String
{
delay(1000)
return "response for $input"
}
Я бы хотел получить что-то вроде этого:
asyncAll(list, ::callRemoteService).awaitAll()
Возможно, я мог бы реализовать это с помощью функций расширения Мне просто интересно, есть ли более идиоматический способ сделать это.
РЕДАКТИРОВАТЬ : Я обнаружил, что awaitAll уже существует. Теперь мне просто нужно asyncAll.
list.map { async { callRemoteService(it) } }.awaitAll().forEach { println(it) }
EDIT2 :
Я написал свою реализацию asyncAll:
fun <T, V> CoroutineScope.asyncAll(
items: Iterable<T>,
function: suspend (T) -> V
): List<Deferred<V>>
{
return items.map { async { function.invoke(it) } }
}
Так что теперь у меня есть это, что выглядит довольно хорошо:
asyncAll(list) { callRemoteService(it) }.awaitAll()
Теперь мне просто интересно, если это что-то уже существует:)
EDIT3 :
Думая об этом, это могло бы даже выглядеть лучше:
list.asyncAll { callRemoteService(it) }.awaitAll()
У меня просто проблемы с реализацией. Так как у меня уже есть получатель, который является итеративным, я не уверен, как я мог бы передать область действия процедуры:
fun <T, V> Iterable<T>.asyncAll(
function: (T) -> V
): List<Deferred<V>>
{
return this.map { async { function.invoke(it) } }
}