Есть ли операторы asyncAll и / или awaitAll для сопрограмм Kotlin? - PullRequest
1 голос
/ 13 апреля 2019

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