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
    }
相关推荐
alexhilton3 小时前
理解Jetpack Compose中副作用函数的内部原理
android·kotlin·android jetpack
人生游戏牛马NPC1号8 小时前
学习Android(四)
android·kotlin
百锦再9 小时前
Kotlin学习基础知识大全(上)
android·xml·学习·微信·kotlin·studio·mobile
张可12 小时前
历时两年半开发,Fread 项目现在决定开源,基于 Kotlin Multiplatform 和 Compose Multiplatform 实现
android·前端·kotlin
xiangxiongfly91514 小时前
Kotlin 边界限制
kotlin·coercein
百锦再20 小时前
Java与Kotlin在Android开发中的全面对比分析
android·java·google·kotlin·app·效率·趋势
喵手1 天前
从 Java 到 Kotlin:在现有项目中迁移的最佳实践!
java·python·kotlin
居然是阿宋1 天前
Kotlin高阶函数 vs Lambda表达式:关键区别与协作关系
android·开发语言·kotlin
wangz761 天前
kotlin的kmp编程中遇到Unresolved reference ‘java‘问题
kotlin·kmp