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

如何在子协程抛出异常时让其他子协程继续执行?

解决子协程异常不影响其他子协程执行的问题

你的代码核心问题在于:两个子协程嵌套在scope.launch创建的普通Job协程下,而非直接挂载到带有SupervisorJob的CoroutineScope上。普通Job的特性是子协程异常会传播到父协程,导致父协程取消所有同级子协程,所以子协程2抛出异常时,外层launch协程会被取消,连带终止子协程1。

要实现子协程2崩溃时子协程1继续执行,只需将两个子协程直接作为scope的顶级子协程启动,而非嵌套在另一个launch中:

suspend fun main() {
    val context = Dispatchers.Default + SupervisorJob()
    val scope = CoroutineScope(context = context)
    
    // 直接在scope下启动两个子协程
    val job1 = scope.launch {
        repeat(25) {
            println("child 1 $it")
            delay(25)
        }
    }
    
    val job2 = scope.launch {
        repeat(20) {
            println("child 2 $it")
            delay(18)
            if (it == 16)
                throw Exception("aaa")
        }
    }
    
    job1.join()
    job2.join() // 等待两个子协程都完成(即使job2异常)
    println("Main finished")
}

关键原理说明

  • SupervisorJob的作用是隔离子协程的异常传播:当某个子协程抛出未捕获异常时,只会取消该子协程本身,不会影响其他同级子协程或父协程。
  • 必须确保两个子协程是SupervisorJob作用域的直接子协程,而非嵌套在普通Job协程下,否则隔离规则不生效。

如果需要处理子协程2的异常,可在其launch块内添加try-catch,避免异常被协程异常处理器捕获(虽然不影响其他协程,但能更优雅地处理错误):

val job2 = scope.launch {
    try {
        repeat(20) {
            println("child 2 $it")
            delay(18)
            if (it == 16)
                throw Exception("aaa")
        }
    } catch (e: Exception) {
        println("子协程2捕获异常:${e.message}")
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 18:42:07