一文带你吃透Kotlin协程的launch()和async()的区别

105 阅读2分钟

核心区别

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)。
  • 需要更灵活地控制异常(如延迟处理)。

更多分享

  1. 一文吃透Kotlin中冷流(Clod Flow)和热流(Hot Flow)
  2. Kotlin日常高效编程技巧和作用域函数的使用。