1

我在一个协程中尝试了 init 三个集合,但只工作了第一个。只有当我设置在不同的协程中收集它的工作时。为什么?

  lifecycleScope.launch {
            launch {
                homeViewModel.dateStateFlow().collect { date ->
                    date?.let { calendar.text = date.toStringForView() }
                }
            }
            launch {
                homeViewModel.toStateFlow().collect { to ->
                    to?.let { cityTo.text = to.name }
                }
            }
            launch {
                homeViewModel.fromStateFlow().collect { from ->
                    from?.let { cityFrom.text = from.name }
                }
            }
        }
4

1 回答 1

4

StateFlow 永远不会完成,因此收集它是一个无限的动作。这在StateFlow 的文档中进行了解释。协程是顺序的,所以如果你调用collectStateFlow,协程中调用之后的任何代码都不会到达。

因为收集 StateFlows 和 SharedFlows 来更新 UI 是很常见的,所以我使用这样的辅助函数来使其更简洁:

fun <T> LifecycleOwner.collectWhenStarted(flow: Flow<T>, firstTimeDelay: Long = 0L, action: suspend (value: T) -> Unit) {
    lifecycleScope.launch {
        delay(firstTimeDelay)
        lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
            flow.collect(action)
        }
    }
}

// Usage:

collectWhenStarted(homeViewModel.dateStateFlow()) { date ->
    date?.let { calendar.text = date.toStringForView() }
}

于 2021-02-05T19:13:36.607 回答