Kotlin中launch与coroutineScope启动协程的差异及适用场景
coroutineScope 与 launch 的核心差异及适用场景
本质与执行逻辑差异
- launch:是
CoroutineScope的扩展函数,调用后会立即启动一个独立的协程,但不会阻塞当前协程的后续代码(除非手动调用返回的Job对象的join()方法)。核心是「启动一个后台任务,不用等它做完就能继续当前工作」。 - coroutineScope:是挂起函数,调用时会创建一个新的协程作用域,并且挂起当前协程,直到该作用域下所有子协程全部执行完毕才会恢复当前协程。它本身不启动协程,而是提供一个「等待所有子任务完成」的容器,需要在里面用
launch/async等启动子协程。
给你修改个例子更直观:
fun main() { println("Main block ${Thread.currentThread().name}") runBlocking { coroutineScope { // 在coroutineScope里启动一个子协程 launch { delay(1000) println("Coroutine scope inner launch done") } println("Coroutine scope ${Thread.currentThread().name}") } // 这行代码会等上面coroutineScope里的子协程完成才会执行 println("After coroutineScope") launch { println("Launch ${Thread.currentThread().name}") } } }
执行顺序是:
- 打印
Main block main - 进入runBlocking,执行coroutineScope
- 打印
Coroutine scope main - 等待1秒后打印
Coroutine scope inner launch done - coroutineScope执行完毕,恢复当前协程,打印
After coroutineScope - 启动launch协程,打印
Launch main
异常处理差异
- launch:启动的协程如果抛出未捕获异常,默认会向上传播给父协程,导致父协程连同其他子协程一起被取消(除非使用
SupervisorJob隔离异常)。 - coroutineScope:会监控作用域内所有子协程,只要有一个子协程抛出异常,整个作用域会立即取消所有其他子协程,然后将异常向上传播。如果想避免「一个子任务失败导致全部取消」,可以用
supervisorScope(coroutineScope的变体)。
适用场景
- 用launch的场景:
- 需要启动后台任务,不阻塞当前流程时,比如UI页面启动后,后台加载数据,同时页面先显示骨架屏。
- 执行不需要等待结果的异步操作,比如日志上报、数据埋点。
- 用coroutineScope的场景:
- 需要并行执行多个任务,必须等所有任务完成后再进行下一步,比如同时请求多个接口,等所有接口返回后再合并展示数据。
- 封装一组必须全部完成的子操作,保证这些操作要么全部成功,要么因异常全部取消。
内容的提问来源于stack exchange,提问作者lager_virtual_machine
相关产品推荐
相关产品推荐

