协程进阶:监督 03. 监督环境下的异常捕获

本篇解析 example-supervision-03.kt。探讨在 supervisorScope 中如何正确地处理子任务的报错。

1. 核心概念:独立责任

supervisorScope 中,由于子任务的异常不会自动向上传播给父作用域,因此每个子协程必须通过 CoroutineExceptionHandler 来处理自己的错误。

执行流程:

  • 子协程报错:它会触发自己上下文中的 handler,然后安静地终止。
  • 作用域正常:由于使用了监督机制,supervisorScope 本身会保持活跃,并正常完成所有的逻辑输出。

2. 代码解析

1
2
3
4
5
6
7
8
9
10
11
val handler = CoroutineExceptionHandler { _, exception -> 
println("CoroutineExceptionHandler got $exception")
}
supervisorScope {
val child = launch(handler) { // 必须在这里传入处理者
println("The child throws an exception")
throw AssertionError()
}
println("The scope is completing") // 这里会正常执行
}
println("The scope is completed") // 这里也会正常执行

3. 开发者感悟

supervisorScope 结合 CoroutineExceptionHandler 是处理复杂并行任务的最佳搭档。它不仅让各个子任务之间互不干扰(“隔离”),还保证了每一个失败的任务都能被优雅地记录。在 Android 中,如果你同时发起三个并行的 API 请求,并希望其中一个报错能显示特定的提示而不影响其他两个正常显示,这套组合就是你的核心武器。

,