在 viewModelScope 中启动的嵌套作业如何工作?

问题描述 投票:0回答:1

我是 Koltin 协程的新手,有时它会让人感到困惑。假设在我的视图模型中我正在收集如下流:

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 将继续工作。 这个概念总体上正确吗?

我想在 state.isOk 为 true 时启动协程 C 并让它收集 res 更新,直到视图模型处于活动状态,但我不确定此实现是否正确。

我认为如果块C被暂停,它不会暂停块A。这是正确的吗?

非常感谢您的帮助。

android kotlin mvvm kotlin-coroutines android-viewmodel
1个回答
1
投票

您对 B 和 C 之间不同行为的描述是正确的。

B 是 A 的子协程,因此当 A 取消时,B 也会被取消。另外,工作 A 在 B 完成之前不会完成。

C 是 B 的兄弟协程,将完全独立运行。由于

viewModelScope
是使用 SupervisorJob 构建的,因此 A 和 C 可以彼此独立地失败。

我认为如果C块被暂停,它不会暂停A块。这是正确的吗?

正确。对于 B 来说本质上也是如此,只不过当 A 到达其

launch
lambda 的末尾时,它仍然会等待启动的 B 完成才能被视为完成。

© www.soinside.com 2019 - 2024. All rights reserved.