首页 > 解决方案 > 作为 CoroutineScope 和启动的参数,Job 有什么不同?

问题描述

这两个代码运行完全相同。将 Job 放入 CoroutineScope 并启动有什么不同?

private val job = CoroutineScope(Dispatchers.Main).launch(start = CoroutineStart.LAZY) {
    for(i in 10 downTo 0) {
        Log.d("test", ": $i")
        delay(1000)
    }
}

CoroutineScope(Dispatchers.Main+job).launch{ }

CoroutineScope(Dispatchers.Main).launch(job) { }

标签: kotlinkotlin-coroutines

解决方案


从技术上讲,两者都会导致相同的行为,但要点是两者都不是使用CoroutineScope()工厂的好方法。这是编写相同内容的惯用方式:

GlobalScope.launch(Dispatchers.Main+job) { ... }

如果这引起了您的注意(“不要使用 GlobalScope! ”),那是因为它应该 - 您的示例只是犯同样错误的另一种方式,代码更冗长。您构造 aCoroutineScope而不持有对它的引用,导致与单例完全相同的无界和不可取消的范围GlobalScope

此外,您使用Job作为实际协程句柄的实例的方式也是错误的:与协程范围关联的作业应该是从Job()或中返回的独立实例SupervisorJob()。它的唯一目的是作为中心点,从中取消整个范围或检查其状态。


推荐阅读