我是Koltin协程的新手,有时候会感到困惑。让我们假设在我的View Model中,我正在收集一个流,如下所示:
viewModelScope.launch A@{
uiState.collect { state ->
// Do something
}
}
只要viewModelScope可用,A 块就应该收集状态。现在,如果我想在collect块内启动另一个作业,该怎么办?
我想如果我这样做
var jobBAlreadyLaunched = false
viewModelScope.launch A@{
uiState.collect { state ->
if (state.isOk && !jobBAlreadyLaunched) {
launch B@{
anotherState.collect { res->
jobBAlreadyLaunched = true
}
}
}
}
}
如果作业 A 取消,则块 B 将被取消。因此我将代码更改为:
var jobCAlreadyLaunched = false
viewModelScope.launch A@{
uiState.collect { state ->
if (state.isOk && !jobCAlreadyLaunched) {
viewModelScope.launch C@{
anotherState.collect { res->
jobCAlreadyLaunched = true
}
}
}
}
}
在本例中,我认为块 C 绑定到 viewModelScope,并且独立于块 A 的协程作用域,因此只要 viewModelScope 处于活动状态,协程 C 就会继续工作。这个概念通常正确吗?
我想启动coroutine C once状态。isOk为true,让它收集 res 更新,直到视图模型激活,但我不确定这个实现是否正确。
我认为如果块 C 被挂起,它不会挂起块 A。对吗?
非常感谢你的帮助。
1条答案
按热度按时间ulydmbyx1#
你对B和C之间不同行为的描述是正确的。
B是A的子协程,所以当A被取消时,它也会被取消。而且,作业A在B完成之前不会完成。
C是B的兄弟协程,并且将完全独立地运行。由于
viewModelScope
是使用SupervisorJob构造的,因此A和C可以彼此独立地失败。我认为如果C块被挂起,它就不会挂起A块,对吗?
正确。这对于B也是基本正确的,除了当A到达其
launch
lambda的末尾时,它仍然会等待启动的B完成,然后才被认为是完成的。