核心区别
launch() | async() | |
---|---|---|
返回值 | 返回Job 表示任务状态 | 返回Deferred<T> 可获取结果T |
用途 | 执行不需要结果的任务 | 执行需要结果的任务 |
异常处理 | 异常会立即传播,会导致协程取消 | 异常暂存,直到调用await() 时抛出 |
使用场景 | 网络请求、IO操作、UI更新 | 合并数据、同时请求多个接口 |
代码示例:
1、launch()
不关心结果
// 启动任务,不等待结果
val jobA = launch { task1() }
val jobB = launch { task2() }
// 继续做其他任务
...
2、async()
需要等待结果
// 启动任务,并等待结果
val deferredA = async { task1() }
val deferredB = async { task2() }
// 等待deferredA和deferredB都好后再做其他任务
val a = deferredA.await()
val b = deferredB.await()
//两个任务并行做,但必须等所有结果好了,才能开始其他任务
val deferredC = async { task3() }
...
重点细节:
1、async()
必须用 await()
取结果
val deferred = async { getUser() }
// 如果不调用await(),结果可能会被忽略,且异常被静默吞掉!
val result = deferred.await()
2、异常处理的不同
launch()
异常会立即取消父协程:
launch {
throw RuntimeException("Exception error!") //会导致父协程取消
}
async()
异常暂存,调用 await()
时才抛出:
val deferred = async { throw RuntimeException("Exception error!") }
delay(1000)
deferred.await() //此出才会抛出异常!
3、async()
+ awaitAll()
处理并发任务
// 同时请求多个接口,等所有结果返回
val deferredA = async { task1() }
val deferredB = async { task2() }
val deferredC = async { task3() }
val results = awaitAll(deferredA, deferredB, deferredC) // 等所有结果
开发中launch()
和 async()
的选择使用场景
launch()
:
- 不需要任务返回结果。
- 独立执行的任务(比如埋点、日志上传等)。
- 需要更简单的异常处理(立即失败)。
async()
:
- 需要并发执行多个任务并汇总结果。
- 需要处理任务间的依赖(如任务A的结果传给任务B)。
- 需要更灵活地控制异常(如延迟处理)。