在协程中并行运行两个 Kotlin 协程

59

我有两个挂起函数:

suspend fun sendData() : Boolean 

suspend fun awaitAcknowledge() : Boolean

我希望你能将它们放在第三个挂起函数中,以便并行执行,并通过两个返回值计算最终结果:

suspend fun sendDataAndAwaitAcknowledge() : Boolean {
    // TODO execute both in parallel and compare both results
}

然而,如果我像那样写,

suspend fun sendDataAndAwaitAcknowledge() : Boolean {
    val sendResult = sendData()
    val receiveAck = awaitAcknowledge()
}

这些函数将按序执行,这在我的情况下行不通。

从 RxJava 来看,我想要实现类似于 zip 操作符的功能:

Single.zip(awaitAcknowledge(), sendData(), {receiveAck, sendResult -> ...})

我该如何使用协程来实现这一点?

2个回答

61

你可以使用 awaitAll 实现该目的:

import kotlinx.coroutines.*

suspend fun sendDataAndAwaitAcknowledge() = coroutineScope {
    awaitAll(async {
        awaitAcknowledge()
    }, async {
        sendData()
    })
}

fun sendData() = true

fun awaitAcknowledge() = false

fun main() {
    runBlocking {
        println(sendDataAndAwaitAcknowledge()) // [false, true]
    }
}

所有函数是否可以在没有毫秒延迟的情况下同时执行? - RaJ

11

使用以下模式:

    suspend fun sendDataAndAwaitAcknowledge() {
     val one = async { sendData() }
     val two = async { awaitAcknowledge() }
     println("The result is ${one.await() + two.await()}")
    }

正如你所看到的,在第三个挂起函数中同时调用了两个挂起函数,第三个挂起函数会等待这两个函数完成它们的任务。


16
你不能仅仅使用async,你需要为它创建协程作用域。 - Andrei Tanana
@AndreiTanana 请查看链接。https://kotlinlang.org/docs/reference/coroutines/composing-suspending-functions.html - user3089483
1
这是示例的完整代码:https://github.com/kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-compose-02.kt,它使用`runBlocking`作用域。 - Andrei Tanana
3
嗯,当我尝试以这种方式实现时,async关键字会出现“未解决的引用”错误。然而,Android Studio没有给出导入建议。 - Christopher
3
这里使用的async是从GlobalScope静态导入的,这并不是一个好的做法。应该在更细粒度的协程作用域中启动async - afollestad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接