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

1 ответ

StateFlow никогда не завершается, поэтому его сбор - бесконечное действие. Это объясняется в документации StateFlow . Сопрограммы являются последовательными, поэтому, если вы вызовете collect в StateFlow ни один код после этого вызова в сопрограмме никогда не будет достигнут.

Поскольку сбор StateFlows и SharedFlows для обновления пользовательского интерфейса является обычным явлением, я использую вспомогательные функции, подобные этой, чтобы сделать его более лаконичным:

      inline fun <T> LifecycleCoroutineScope.collectWhenStarted(flow: SharedFlow<T>, delay: Long = 0L, crossinline action: suspend (value: T) -> Unit) {
    launchWhenStarted {
        delay(delay)
        flow.collect(action)
    }
}

// Usage:

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

Другие вопросы по тегам