Kotlin协程supervisorScope为何未等待所有launch执行完毕?
问题分析与解决
问题原因
你当前的代码逻辑有误:supervisorScope的挂起等待是在其内部代码块全部执行完毕后才会触发。也就是说,你在启动6个launch子协程后立刻执行Log.v("myFunc", "finished count"),这个打印操作是在子协程还在运行时就执行了,而非等所有子协程完成后才执行。supervisorScope只是在打印完成后才开始等待子协程结束,这就导致了日志里finished count先于fun4的输出出现。
解决方法
有两种方式可以实现你想要的“所有函数执行完毕后再打印最终语句”的需求:
方法一:将打印语句移到supervisorScope外部
supervisorScope本身会挂起直到所有内部子协程完成,所以把打印放在它外面,就能保证打印操作在所有子协程结束后执行:
viewModelScope.launch(dispatchers.IO) { supervisorScope { launch { fun1() } launch { fun2() } launch { fun3() } launch { fun4() } launch { fun5() } launch { fun6() } } Log.v("myFunc", "finished count") }
方法二:收集子协程Job并调用joinAll()
在supervisorScope内部,把每个launch返回的Job收集起来,调用joinAll()等待所有子协程完成后再打印:
viewModelScope.launch(dispatchers.IO) { supervisorScope { val jobs = listOf( launch { fun1() }, launch { fun2() }, launch { fun3() }, launch { fun4() }, launch { fun5() }, launch { fun6() } ) jobs.joinAll() Log.v("myFunc", "finished count") } }
两种方法都能让finished count在所有函数(包括带延迟的fun4)执行完毕后才输出。
内容的提问来源于stack exchange,提问作者j2emanue
相关产品推荐
相关产品推荐

