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

Chr*_*her 21 android kotlin kotlin-coroutines

我有两个挂起功能:

suspend fun sendData() : Boolean 

suspend fun awaitAcknowledge() : Boolean
Run Code Online (Sandbox Code Playgroud)

我想将它们包装在第三个挂起函数中,它们应该在其中并行执行,并且我想通过具有两个返回值来计算最终结果:

suspend fun sendDataAndAwaitAcknowledge() : Boolean {
    // TODO execute both in parallel and compare both results
}
Run Code Online (Sandbox Code Playgroud)

但是,如果我这样写的话,

suspend fun sendDataAndAwaitAcknowledge() : Boolean {
    val sendResult = sendData()
    val receiveAck = awaitAcknowledge()
}
Run Code Online (Sandbox Code Playgroud)

这些函数将按串行顺序执行,这在我的情况下不起作用。

来自 RxJava,我想实现类似zip操作符的功能:

Single.zip(awaitAcknowledge(), sendData(), {receiveAck, sendResult -> ...})
Run Code Online (Sandbox Code Playgroud)

我怎样才能做到这一点Coroutines

Ale*_*hin 19

您可以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]
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 12

这是一般模式:

suspend fun sendDataAndAwaitAck() = coroutineScope {
  val one = async { sendData() }
  val two = async { awaitAck() }
  println("The result is ${one.await()}, ${two.await()}")
}
Run Code Online (Sandbox Code Playgroud)

这两个挂起函数(sendDataawaitAck)是从另一个挂起函数(sendDataAndAwaitAck)中调用的。它们可能会并行运行,具体取决于环境和 CPU 设置。外部挂起函数将等待两个内部函数完成其任务然后再继续。

注 1async仅在协程作用域中可用。

注 2:如果您不希望当子协程之一失败时整个范围都失败,supervisorScope则应该使用。

  • 你不能只使用“async”。你需要它的协程作用域 (16认同)
  • 嗯,当我尝试以这种方式实现时,我在“async”关键字上得到“未解析的引用”。但是,我没有从 Android Studio 收到导入建议。 (3认同)
  • 这里使用的“async”是从“GlobalScope”静态导入的,这并不是一个很好用的东西。异步应该在更细粒度的协程范围内启动。 (3认同)