gpt4 book ai didi

android - StateFlow 设置值会丢弃一些事件,但更新不会

转载 作者:行者123 更新时间:2023-12-05 09:27:48 25 4
gpt4 key购买 nike

在我的应用中,我有一个 UIState 密封类来表示 UI 状态。

sealed class UIState<T> {
class ShowLoading<T> : UIState<T>()
class HideLoading<T> : UIState<T>()
class ShowEmptyData<T> : UIState<T>()
class ShowData<T>(val data: T) : UIState<T>()
class ShowError<T>(val errorUIState: ErrorUIState) : UIState<T>()
}

因此,我的 viewmodel 代码是:

 someRequest.apply { response ->
when (response) {
is ApiResponse.Success -> {
_uiStateFlow.value = (UIState.HideLoading()) // First, hide the loading
// Do some work
_uiStateFlow.value = (UIState.ShowData(data))
}
is ApiResponse.Error -> {
_uiStateFlow.value = (UIState.ShowError(error))
}
}
}

在这种情况下,大多数时候我的 hideLoading 状态不会收集,它会下降,因为成功/错误状态会在 hideLoading 之后立即出现,而我的 UI 不会收集它。例如。如果我将延迟成功/错误状态设置为 100 毫秒,hideLoading 将从 UI 中收集。我使用 collect 而不是 collectLatest

但后来我发现,当我更改设置值部分以更新 {} 时,UI 会收集所有状态。

someRequest.apply { response ->
when (response) {
is ApiResponse.Success -> {
_uiStateFlow.update { (UIState.HideLoading()) } // First, hide the loading
// Do some work
_uiStateFlow.update { (UIState.ShowData(data)) }
}
is ApiResponse.Error -> {
_uiStateFlow.update { (UIState.ShowError(error)) }
}
}
}

那么 .value 和 update 之间有什么区别,为什么这个效果很好?谢谢。

附言我也使用过 emit()。在底层,它与 .value 相同,只是一个挂起函数。

最佳答案

StateFlow documentation 中所述:

Updates to the value are always conflated.

Conflated 意味着如果值的发布速度比它们的收集速度快,那么收集器只会获得最新的结果。这允许始终将值发布到 StateFlow,而无需等待收集旧值。

至于为什么update允许加载状态通过,我怀疑这只是因为原子更新通常需要更长的时间,因此收集器通常会赢得比赛,在您的特定测试设备上的这种特定情况下。这不是确保收集器获得所有中间值的可靠解决方案。

我不明白为什么您首先需要 HideLoading 状态。您的 UI 可以在接收到要显示的数据时自动隐藏加载状态。从逻辑上讲,当数据返回时加载完成。

如果你真的需要这个 HideLoading 状态,你应该使用带有 replay 的 SharedFlow足够大的值以确保它不会被跳过。但这会带来其他问题,比如收集者可能会得到过时的数据来展示,因为这些数据正在向他们重放。

旁注,您的密封类可能应该是一个密封接口(interface),因为它没有状态,并且它的没有状态的子级可以是 object s 的泛型类型为 Nothing因此,您不必为了使用它们而继续实例化它们,也不必在它们根本不持有该类型时不必要地指定泛型类型。由于其他的是数据包装器,它们也可能是 data类。像这样:

sealed interface UIState<out T> {
object ShowLoading : UIState<Nothing>
// object HideLoading : UIState<Nothing>
object ShowEmptyData : UIState<Nothing>
data class ShowData<out T>(val data: T) : UIState<T>
data class ShowError(val errorUIState: ErrorUIState) : UIState<Nothing>
}

关于android - StateFlow 设置值会丢弃一些事件,但更新不会,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72088857/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com