У меня есть коллекция, и я хочу выполнить некоторые операции со всеми ее элементами асинхронно в 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) } }
}