Kotlin中如何处理Deferred列表的异常以获取成功执行的返回元素
实现方案
你可以通过两种常用方式实现需求,核心逻辑是单独捕获每个Deferred调用await时抛出的异常,避免单个任务失败终止整个处理流程:
方案1:直接遍历Deferred列表逐个安全await
适合你已经提前拿到所有Deferred实例的场景,不需要额外的协程作用域配置:
val resultList = listOf( getItem1Async(), getItem2Async(), // 该任务异常不会影响其他任务 getItem3Async() ).map { deferred -> // 单个Deferred await失败返回null,你也可以替换为自定义默认值 runCatching { deferred.await() }.getOrNull() } // 如果需要过滤掉失败的空结果,直接调用过滤方法即可 val validResults = resultList.filterNotNull()
方案2:配合SupervisorScope启动异步任务
如果你是在同一个协程作用域内启动所有异步任务,建议搭配supervisorScope使用,它的特性是单个子协程失败不会取消其他子协程,也不会终止父作用域:
suspend fun <T> fetchAllItems(): List<T?> = supervisorScope { listOf( async { getItem1Async().await() }, async { getItem2Async().await() }, async { getItem3Async().await() } ).map { deferred -> runCatching { deferred.await() }.getOrNull() } }
注意事项
- 你提到的
CoroutineExceptionHandler是全局未捕获协程异常的兜底处理组件,无法拦截业务代码中await抛出的异常,因此不适合该场景。 - 如果你已经提前创建完所有Deferred实例(如你的示例代码),不需要额外配置
SupervisorJob也可以实现需求,只要在await时单独捕获异常即可。 - 如果需要自定义默认值,把
getOrNull()替换为getOrDefault(你的自定义默认值)即可。
内容的提问来源于stack exchange,提问作者Nicolas Vivas
相关产品推荐
相关产品推荐

