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

使用viewModelScope(含SupervisorJob)为何第三个launch协程被取消?

问题原因分析

你的代码里第三个launch没打印"API 3"的核心原因是:外层viewModelScope.launch(handler)创建的是普通Job协程,而非SupervisorJob。

虽然viewModelScope的根协程上下文用的是SupervisorJob(),但你内部的三个launch是外层这个普通Job协程的子协程,并非viewModelScope的直接子协程。而普通Job的特性是:只要有一个子协程抛出未捕获的异常,整个Job会被立即取消,所有关联的子协程都会被终止。

对应你的代码流程:

  1. 三个子协程同时启动,分别开始执行
  2. 1秒后第一个协程打印"API 1"
  3. 1.5秒后第二个协程抛出NullPointerException
  4. 外层的普通Job检测到子协程异常,立刻取消所有子协程(包括第三个还在执行delay(2000)的协程)
  5. 外层的CoroutineExceptionHandler捕获到异常并打印信息,但此时第三个协程已经被终止,无法完成后续的打印
解决办法

要让内部子协程的异常不互相牵连,有两种常用方案:

方案1:直接将子协程作为viewModelScope的直接子协程

去掉外层的launch(handler),让三个子协程直接挂在viewModelScope的SupervisorJob下,同时给需要处理异常的协程单独设置异常处理器:

fun test() {
    viewModelScope.launch {
        launch(handler) {
            println("API 1 launch executing")
            apiCall("API 1", 1000)
        }
        launch(handler) {
            println("API 2 launch executing")
            delay(1500)
            throw NullPointerException("Exception")
        }
        launch {
            println("API 3 launch executing")
            apiCall("API 3", 2000)
        }
        delay(4000)
        println("API no api its ended.")
    }
}

方案2:用supervisorScope包裹内部子协程

在外层launch里用supervisorScope创建一个局部的SupervisorJob作用域,这样内部的子协程异常只会终止自身,不会影响其他协程:

fun test() {
    viewModelScope.launch(handler) {
        supervisorScope {
            launch {
                println("API 1 launch executing")
                apiCall("API 1", 1000)
            }
            launch {
                println("API 2 launch executing")
                delay(1500)
                throw NullPointerException("Exception")
            }
            launch {
                println("API 3 launch executing")
                apiCall("API 3", 2000)
            }
        }
        delay(4000)
        println("API no api its ended.")
    }
}

这两种方案都能让第三个协程正常执行并打印"API 3",同时异常会被正确捕获。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 13:25:14