Return 更快协程的特定值

Return a specific value only of the faster coroutine

我正在开发 Kotlin Android 应用程序 在我的应用程序中,我需要 运行 多个并行的协程,我想 return 只有第一个完成的协程的第一个非空值?

我使用了 select 表达式,在那里找到了示例:https://kotlinlang.org/docs/select-expression.html#selecting-deferred-values

import kotlinx.coroutines.*
import kotlinx.coroutines.selects.*
import java.util.*
    
fun CoroutineScope.asyncString(time: Int) = async {
    delay(time.toLong())
    null
}

fun CoroutineScope.asyncStringsList(): List<Deferred<String>> {
    val random = Random(3)
    return List(12) { asyncString(random.nextInt(1000)) }
}

fun main() = runBlocking<Unit> {
    val list = asyncStringsList()
    val result = select<String> {
        list.withIndex().forEach { (index, deferred) ->
            deferred.onAwait { answer ->
              answer
           }
        }
    }
    println(result)
}

在我的例子中,它将是:

        list.withIndex().forEach { (index, deferred) ->
            deferred.onAwait { answer ->
              if (answer == null) return else answer
           }
        }

但是我有这个错误:这里不允许'return'。

有什么建议吗?

谢谢

我对select 子句的处理不多,我不知道如何有选择地选择是否拒绝一个结果并等待下一个结果。 (似乎是一个关键的缺失功能。)

我认为您可以使用 channelFlow 执行类似的操作。它为每个 Deferred 启动并行协程,它们按顺序由 Flow 发出,因此您可以使用 first().

过滤并选择第一个协程
fun main() = runBlocking {
    val list = asyncStringsList()
    val result = channelFlow {
        list.forEach { launch { send(it.await()) } }
    }
        .filterNotNull()
        .first()
    println(result)
}