Kotlin协程是否有asyncAll和/或awaitAll运算符?

时间:2019-04-13 09:42:04

标签: kotlin kotlin-coroutines

我有一个集合,我想在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()

我只是在实现方面遇到麻烦。由于我已经在这里有了一个可迭代的接收器,因此我不确定如何通过Couroutine范围:

fun <T, V> Iterable<T>.asyncAll(
    function: (T) -> V
): List<Deferred<V>>
{
    return this.map { async { function.invoke(it) } }
}

1 个答案:

答案 0 :(得分:0)

终于得到了我想要的解决方案。我需要这个扩展功能:

suspend fun <T, V> Iterable<T>.asyncAll(coroutine: suspend (T) -> V): Iterable<V> = coroutineScope {
    this@asyncAll.map { async { coroutine(it) } }.awaitAll()
}

我可以这样使用它:

list.asyncAll { callRemoteService(it) }.forEach { println(it) }

我不确定命名。也可以是 asyncMap