前言

在使用Kotlin协程时,经常使用到launchasync,都新协程的构建器,这里简单记录一下,方便自己查阅和学习。

正文

launch

launch即发即忘的后台任务。

当你只关心任务是否执行,而不关心其返回结果时,应使用 launch。它返回的 Job 对象仅用于管理协程的生命周期,例如取消任务或等待其完成。

典型场景:埋点上报、日志记录、UI 状态刷新、发送通知等。

fun main() = runBlocking {
    val job = launch {
        delay(1000L) // 模拟耗时操作
        //略
    }
    // 如果需要,可以等待任务完成
    job.join()
}

async

async并发执行并汇总结果。

当你需要同时执行多个耗时任务,并等待所有结果返回后再进行下一步处理时,async 是最佳选择。它返回的 Deferred<T> 对象封装了异步计算的结果,必须通过 await() 来获取。

典型场景:并行请求多个网络接口、并发处理数据、存在数据依赖的并发任务等。

fun main() = runBlocking {
    val userDeferred = async {
        delay(1000L) // 模拟网络请求
        //用户数据处理
    }
    val orderDeferred = async {
        delay(1000L) // 模拟网络请求
        //订单数据处理
    }
    // 等待两个任务都完成并获取结果
    val user = userDeferred.await()
    val order = orderDeferred.await()
}

小结

  1. async必须调用 await()如果启动了 async 却忘记调用 await(),不仅无法获取结果,其内部抛出的异常也会被静默吞掉,导致难以排查的 Bug。

  2. 避免过度设计如果任务之间是顺序依赖关系,或者没有并发需求,直接在 launch 中按顺序调用挂起函数即可,代码更直观。对于单个需要返回结果的耗时任务,使用 withContextasync { ... }.await() 语义更清晰、开销更小。

  3. 异常处理机制不同launch 中的异常会立即抛出,而 async 中的异常只有在调用 await() 时才会抛出。在使用 async 时,务必将 await() 放在 try-catch 块中,以确保异常能被正确捕获和处理。

对比

特性launchasync
设计语义启动一个任务(即发即忘)启动一个带结果的任务
返回类型JobDeferred<T>
获取结果不支持必须通过 await() 获取
异常处理异常立即传播,可能导致协程取消或崩溃异常被暂存,直到调用 await() 时才抛出

参考文章

  1. AI

  2. Kotlin资料

相关文章

笔友城堡 - 可定义的个人主页

暂无评论

评论审核已启用。您的评论可能需要一段时间后才能被显示。

none
暂无评论...