android viewModelScope中的嵌套作业是如何工作的?

myss37ts  于 2023-04-28  发布在  Android
关注(0)|答案(1)|浏览(148)

我是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。对吗?
非常感谢你的帮助。

ulydmbyx

ulydmbyx1#

你对B和C之间不同行为的描述是正确的。
B是A的子协程,所以当A被取消时,它也会被取消。而且,作业A在B完成之前不会完成。
C是B的兄弟协程,并且将完全独立地运行。由于viewModelScope是使用SupervisorJob构造的,因此A和C可以彼此独立地失败。
我认为如果C块被挂起,它就不会挂起A块,对吗?
正确。这对于B也是基本正确的,除了当A到达其launch lambda的末尾时,它仍然会等待启动的B完成,然后才被认为是完成的。

相关问题