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

Kotlin中runBlocking未生效求助:getGroupSummaries执行顺序异常

问题:runBlocking未正常阻塞导致后续代码提前执行

场景说明

我需要在后续代码执行前,确保suspend fun getGroupSummaries完全执行完毕,但当前实现出现异常:

  • 打印groupInformationList大小的日志,反而先于getGroupSummaries内部日志输出
  • 外部日志显示集合大小为0,但函数内部日志显示大小为1
    另外,制作最小复现示例时,移除循环后运行正常。

相关代码

函数声明

suspend fun getGroupSummaries(groupInfo: GroupInformation, adminUserInfo: UserInformation){
    // 内部逻辑,会修改groupInformationList
}

当前调用代码

runBlocking {
    val getGroupSummariesJob = viewModelScope.launch {
        getGroupSummaries(groupInformation, userInformation)
    }
    getGroupSummariesJob.join()
}

Timber.e("After getGroupSummaries, groupInformationList size = " + groupInformationList.size)

问题原因

viewModelScope默认使用Dispatchers.Main调度器,而runBlocking会阻塞当前线程(通常是主线程)。主线程被阻塞后,viewModelScope.launch启动的协程会被卡在主线程的任务队列里,根本没机会执行——join()只是等待Job的状态,但协程本身没运行,所以后续代码会提前执行,导致日志顺序颠倒、集合数据未更新。

解决建议

方案1:直接在runBlocking作用域内调用挂起函数

runBlocking本身就是协程作用域,直接调用挂起函数会自动等待其完成,无需额外启动Job:

runBlocking {
    getGroupSummaries(groupInformation, userInformation)
}
Timber.e("After getGroupSummaries, groupInformationList size = " + groupInformationList.size)

方案2:给viewModelScope.launch指定非主线程调度器

让协程在后台线程执行,避免被runBlocking阻塞的主线程影响:

runBlocking {
    val getGroupSummariesJob = viewModelScope.launch(Dispatchers.IO) {
        getGroupSummaries(groupInformation, userInformation)
    }
    getGroupSummariesJob.join()
}
Timber.e("After getGroupSummaries, groupInformationList size = " + groupInformationList.size)

方案3:避免用runBlocking阻塞主线程(推荐)

如果是在ViewModel中编写逻辑,直接用viewModelScope启动协程,在挂起函数执行完成后再处理后续逻辑:

viewModelScope.launch {
    getGroupSummaries(groupInformation, userInformation)
    Timber.e("After getGroupSummaries, groupInformationList size = " + groupInformationList.size)
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 09:06:15