Kotlin 协程:withContext 与 async 核心区别与使用场景
核心定位
withContext 是为了获取结果 ,async 是为了并发 。
单任务切换线程获取数据时,async/await 属于「杀鸡用牛刀」,withContext 更适配。
为什么 withContext 在单任务场景下更优?
1. 写法更直观(少一层包装)
- async/await:返回 Deferred 包装对象,必须手动
await()拆包 - withContext:直接返回执行结果,无需手动拆包
kotlin
// 使用 async (略显啰嗦)
val deferred = async(Dispatchers.IO) { api.getUser() }
val user = deferred.await() // 必须手动 await
// 使用 withContext (一气呵成)
val user = withContext(Dispatchers.IO) { api.getUser() } // 直接拿结果
2. 异常处理更安全
- async:异常会封装在 Deferred 中,仅调用
await()时抛出,复杂逻辑易遗漏处理 - withContext:执行异常立即在当前位置抛出,可直接外层套
try-catch,结构清晰
3. 性能更优(微小但存在)
withContext 不会创建新协程对象,仅在同一协程内切换调度器;
async 会创建新的子协程,高频简单逻辑调用时,withContext 更轻量。
什么时候必须用 async?
withContext 会阻塞当前协程 (等待结果返回后再执行后续逻辑),
需要多任务并行执行时,必须使用 async:
kotlin
// 两个请求同时发出,总耗时 = 耗时较长的单个请求
val userDeferred = async { api.getUser() }
val postsDeferred = async { api.getPosts() }
val result = userDeferred.await() + postsDeferred.await()
总结
- 单任务切换线程(获取数据、读取文件):无脑选择 withContext
- 多任务并行(同时执行多个任务):选择 async