You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何并行执行两个挂起函数并返回先完成的结果?

解决思路

你的问题核心在于使用了awaitAll()——这个方法会强制等待所有Deferred对象执行完毕才返回结果,所以必须等两个挂起函数都跑完才能继续。要实现「取第一个完成的结果就返回」的逻辑,可以用以下两种方式:

方案一:使用select表达式(兼容大多数Kotlin版本)

利用select监听两个Deferred的完成事件,第一个完成的会直接触发分支返回结果,之后记得取消未完成的协程避免资源浪费:

// 建议用结构化并发作用域,比如viewModelScope、lifecycleScope,或者在suspend函数里用coroutineScope
coroutineScope {
    val deferredA = async(Dispatchers.IO) { a(context) }
    val deferredB = async(Dispatchers.IO) { b(context) }

    // 监听第一个完成的结果
    val firstResult = select<Any> {
        deferredA.onAwait { it }
        deferredB.onAwait { it }
    }

    // 取消未完成的协程
    if (deferredA.isActive) deferredA.cancel()
    if (deferredB.isActive) deferredB.cancel()

    return@coroutineScope if (firstResult is RunSuccess) {
        // 处理成功逻辑
    } else {
        // 处理非成功情况
    }
}

方案二:使用race函数(Kotlin 1.7.0+ 推荐)

Kotlin Coroutines 1.7.0及以上版本提供了race函数,它会自动并行执行多个挂起块,返回第一个完成的结果,并且自动取消其他未完成的协程,代码更简洁:

val firstResult = coroutineScope {
    race {
        launch { a(context) }
        launch { b(context) }
    }
}

return if (firstResult is RunSuccess) {
    // 处理成功逻辑
} else {
    // 处理非成功情况
}

注意事项

  • 尽量使用结构化并发作用域(比如viewModelScope、lifecycleScope或suspend函数内的coroutineScope),避免手动创建全局CoroutineScope,防止内存泄漏。
  • 如果其中一个函数抛出异常,需要根据业务需求在async或launch块内添加try-catch处理异常逻辑。

内容的提问来源于stack exchange,提问作者ZookKep

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 23:54:30