运行 异步协程与 Pair return

Running async coroutine with Pair return

当它 return 只有一个值时,我可以使用异步调用函数。

但是,如果 return 是一对,我得到 - Destructuring declaration initializer of type Deferred<Unit> must have a 'component1()' function

我是不是漏掉了什么?

这是一个示例代码:

import kotlinx.coroutines.async
import kotlinx.coroutines.runBlocking

fun main() = runBlocking {
    val num = 11
    val a = async { oneValue(num) }
    println(a.await()) // returns 22

    // This doesn't compile
    val (b, c) = async { twoValues(num) } // Destructuring declaration initializer of type Deferred<Unit> must have a 'component1()' function
    println(b.await())
    println(c.await())
    
    // Same code works without async-await
    val (d, e) = twoValues(num)
    println(d)
    println(e)

}

suspend fun oneValue(num: Int): Int {
    return num * 2
}

suspend fun twoValues(num: Int): Pair<Int, Boolean> {
    return Pair(num * 2, true)
}

问题是您只能通过这种方式解构 Pair,而不能解构 Deferred 本身。

您可以先将延迟值分配给单个变量,然后 await 它这样您就可以得到一个 Pair 可以解构:

val deferredPair = async { twoValues(num) }

// do other stuff concurrently

val (b, c) = deferredPair.await()
println(b)
println(c)

如果你真的不需要与这个 twoValues() 同时做任何事情,你也可以直接调用它(就像你在上一个例子中所做的那样):

val (b, c) = twoValues(num)
println(b)
println(c)

请注意,您的挂起函数在这里进行了全部计算,然后然后 returns Pair 两个计算对象。它不提供等待它的一部分的可能性。这可能是你要找的,所以应该没问题。

如果您需要有 2 个可以独立等待的独立计算,则需要启动 2 个协程,这会使事情变得有点复杂。最有可能的是,如果这是你想要的,计算可能足够独立,可以放入 2 个不同的挂起函数中,你可以在 2 个单独的异步中调用它们(所以你回到了已知的情况,即只有一个 return值)。