Kotlin 协程 launch 和 async 的区别

Kotlin 协程 launch 和 async 的区别

  • launch 和 async 都是用于启动协程的函数,都是 CoroutineScope 接口的扩展函数
  • launch 用于执行无需返回值的异步任务(比如日志上传、埋点和 IO 操作)
  • async 用于执行并发任务并汇总结果的场景(比如多个接口并行请求后合并数据)

launch

  • launch 返回 Job 对象,用于控制协程生命周期(比如取消协程、等待协程完成)
  • 异常处理:异常立即传播,导致协程取消(取消整个协程作用域),可通过 try-catch 捕获
kotlin 复制代码
val job = launch { 
    //执行后台任务
}
job.join() //等待协程完成,但不获取结果
kotlin 复制代码
suspend fun suspendFun_fetchDoc1(): String {
    delay(5000)
    return "text01"
}

suspend fun suspendFun_fetchDoc2(): String {
    delay(3000)
    return "text02"
}
//并行
suspend fun fetchTwoDocs() =
    coroutineScope {
        val job1 = launch(Dispatchers.IO) { suspendFun_fetchDoc1() }
        val job2 = launch(Dispatchers.IO) { suspendFun_fetchDoc2() }
        //suspendFun_fetchDoc1 和 suspendFun_fetchDoc2 两个是并行的
        job1.join()
        job2.join()
        println("fetchTwoDocs end")
    }
//串行
suspend fun fetchTwoDocs2() =
    coroutineScope {
        //suspendFun_fetchDoc1 和 suspendFun_fetchDoc2 两个是串行的
        val job1 = launch(Dispatchers.IO) { suspendFun_fetchDoc1() }
        job1.join() //launch 后立即调用 join,相当于等待任务 1 完成后再执行任务 2
        val job2 = launch(Dispatchers.IO) { suspendFun_fetchDoc2() }
        job2.join()
        println("fetchTwoDocs2 end")
    }

async

  • async 返回 Deferred 对象(Deferred 继承自 Job,额外提供 await 方法用于获取结果)
  • 异常处理:异常暂存在 Deferred 中,直到调用 await 方法时抛出
kotlin 复制代码
val deferred = async {
    //...
    "数据结果" //必须有返回值
}
val result = deferred.await() //阻塞等待结果
kotlin 复制代码
suspend fun suspendFun_fetchDoc1(): String {
    delay(5000)
    return "text01"
}
suspend fun suspendFun_fetchDoc2(): String {
    delay(3000)
    return "text02"
}
//并行
suspend fun fetchTwoDocs() =
    coroutineScope {
        val deferred1 = async(Dispatchers.IO) { suspendFun_fetchDoc1() }
        val deferred2 = async(Dispatchers.IO) { suspendFun_fetchDoc2() }
        //suspendFun_fetchDoc1 和 suspendFun_fetchDoc2 两个是并行的
        val result1 = deferred1.await()
        val result2 = deferred2.await()
        println("fetchTwoDocs result1=$result1 result2=$result2")
        //----------------- 打印 -----------------
        //fetchTwoDocs result1=text01 result2=text02
    }
//并行
suspend fun fetchTwoDocs2() =
    coroutineScope {
        val deferred1 = async(Dispatchers.IO) { suspendFun_fetchDoc1() }
        val deferred2 = async(Dispatchers.IO) { suspendFun_fetchDoc2() }
        //suspendFun_fetchDoc1 和 suspendFun_fetchDoc2 两个是并行的
        val resultList = awaitAll(deferred1, deferred2) //和 Collection#awaitAll 逻辑基本一致
        resultList.forEachIndexed { index, result ->
            println("fetchTwoDocs2 index=$index result=$result")
        }
        //----------------- 打印 -----------------
        //fetchTwoDocs2 index=0 result=text01
        //fetchTwoDocs2 index=1 result=text02
    }
//串行
suspend fun fetchTwoDocs3() =
    coroutineScope {
        //suspendFun_fetchDoc1 和 suspendFun_fetchDoc2 两个是串行的
        val deferred1 = async(Dispatchers.IO) { suspendFun_fetchDoc1() }
        val result1 = deferred1.await() //async 后立即调用 await,相当于等待任务 1 完成后再执行任务 2
        val deferred2 = async(Dispatchers.IO) { suspendFun_fetchDoc2() }
        val result2 = deferred2.await()
        println("fetchTwoDocs3 result1=$result1 result2=$result2")
        //----------------- 打印 -----------------
        //fetchTwoDocs3 result1=text01 result2=text02
    }
//串行
suspend fun fetchTwoDocs4() =
    coroutineScope {
        //suspendFun_fetchDoc1 和 suspendFun_fetchDoc2 两个是串行的
        val result1 = withContext(Dispatchers.IO) { suspendFun_fetchDoc1() }
        val result2 = withContext(Dispatchers.IO) { suspendFun_fetchDoc2() }
        println("fetchTwoDocs4 result1=$result1 result2=$result2" )
        //----------------- 打印 -----------------
        //fetchTwoDocs4 result1=text01 result2=text02
    }
相关推荐
不要喷香水5 小时前
00-总览与架构
kotlin·app·档案管理
hai_android6 小时前
Android 组件化开发实践
android·java·kotlin
传奇开心果编程1 天前
【Jetpack Compose基础语法学与练】第6课 TextField文本输入,字符串状态与输入交互
学习·前端框架·kotlin·android jetpack
ai2work1 天前
ch06 Jetpack Compose 入门:状态驱动 UI
kotlin
JMchen2 天前
第 12 篇|项目整合与打包发布 —— 从 Demo 到可安装 APK 的完整收官指南
kotlin·android studio
Android打工仔2 天前
不要在 Data 层随意把 Cold Flow 转换成 Hot Flow
android·架构·kotlin
杉氧2 天前
拒绝重复造轮子:我写了一个生产级的 Kotlin 协程与 Flow 工具库(CoroutineKit)
android·kotlin·workflow
JMchen3 天前
第 9 篇|网络请求基础 —— 从 HttpURLConnection 到 OkHttp
kotlin·android studio
hai_android4 天前
Kotlin Flow combine 源码剖析:一个 Channel 如何优雅合并多条流
android·java·kotlin
敲代码的瓦龙4 天前
Jetpack?ViewModel!!!
android·开发语言·kotlin·android-studio