如何并行执行两个挂起函数并返回先完成的结果?
解决思路
你的问题核心在于使用了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
相关产品推荐
相关产品推荐

