这是一个令人困惑的工作是什么意思的过载.每个协程作业(job)都有一个父作业(job).即使是直接从CoroutineScope启动的最顶层的协程也有一个父作业(job),在本例中,它是一个isn'ta协程的作业(job).
您传递给CoroutineScope"构造函数*"的作业(job)是由该作用域直接启动的协程的父作业(job).它本身并不代表协程,但它将具有子协程.
CoroutineContext始终包括作为当前协程的父级的作业(job),并且始终包括管理正在使用的线程的调度程序.当您深入到协程的嵌套lambdas中时,内部的launch
、async
和withContext
块可能会局部修改CoroutineContext.
代码Job() + Dispatchers.Default
创建了一个具有这两个元素的CoroutineContext.**
实际上没有必要将纯Job()
传递给CoroutineScope构造函数,因为如果省略它,无论如何都会生成一个,因为它是必需的元素.
更常见的是传递一个SupervisorJob()
作为默认CoroutineContext的一部分.这种类型的作业(job)允许其子协同 routine 彼此独立地失败(一个失败的协同 routine 不会导致其余的协同 routine 被取消).人们通常希望CoroutineScope的这种行为将用于运行可能不相互依赖的多个协程.这就是lifecycleScope
和viewModelScope
是如何在Android的引擎盖下创建的.
除了作业(job)和调度程序,我认为使用+ CoroutineName("...")
也是一个好主意,这样您的错误日志(log)会更有帮助.
*它实际上只是一个看起来像构造函数的函数.
**CoroutineContext的行为类似于一个不可变的Map,其中它的键是JOB、CoroutineInterceptor(Dispatcher的超类型)、CoroutineName和CoroutineExceptionHandler的伴随对象.当您在CoroutineContext元素上使用+
时,它会将它们合并到一个新的CoroutineContext中,该新的CoroutineContext仍然 for each 键都有一个值.我认为可以创建您自己的密钥,并使用它们来附加传递到协程中的额外数据,但我从未try 过这一点.