微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

StateFlow 收集在一个协程中

如何解决StateFlow 收集在一个协程中

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

  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 }
                }
            }
        }

解决方法

StateFlow 永远不会完成,因此收集它是一个无限的操作。这在 the documentation of StateFlow 中有解释。协程是连续的,因此如果您在 StateFlow 上调用 collect,则协程中该调用之后的任何代码都不会被访问。

由于收集 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() }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。