Kotlin 协程的启动方式

相关概念:kotlin

一句话记忆:

协程是在 CoroutineScope 上下文里,通过 launchasync 这类协程构造器启动的。

最常见的入口

runBlocking

适合主函数、测试代码,或者需要把异步流程桥接回同步世界的时候:

fun main() = runBlocking {
    launch {
        delay(1000)
    }
}

coroutineScope

适合挂在已有挂起函数里,表达“在当前作用域下并发做几件事,然后一起收口”:

suspend fun loadData() = coroutineScope {
    launch {
        // ...
    }
}

指定上下文启动

launch(Dispatchers.IO) {
    // ...
}

这表示把协程调度到更适合 IO 的上下文里运行。

GlobalScope 为什么不该成为默认选项

像下面这种写法当然能跑:

GlobalScope.launch(Dispatchers.IO) {
    delay(1000)
}

但它的问题是生命周期太松,很容易变成“任务发出去了,但没人负责它什么时候结束、失败了怎么办”。

所以工程代码里更适合:

  • 绑定到明确的作用域
  • 让生命周期跟业务边界一起收口

判断标准

看到“需要启动协程”时,先不要急着写 launch,先问几个边界问题:

  • 这个协程属于谁的生命周期
  • 失败要不要向上抛
  • 是否需要结果,还是只需要执行

然后再决定用:

  • launch:只关心执行
  • async:还需要结果

经验

协程真正难的地方通常不在“怎么启动”,而在“作用域归谁管”。

只要作用域清楚,协程代码一般都会干净很多。