如何获取Flow
的最新值?我没有需要最新值的StateFlow
。这是一个浓缩的场景:
有一个存储库暴露StateFlow
val repositoryExposedStateFlow: StateFlow<SomeType> = MutableStateFlow(...)
此外,还有映射器将StateFlow
转换为类似
val mappedFlow: Flow<SomeOtherType> = repositoryExposedStateFlow.flatMapLatest { ... }
mappedFlow
不再是StateFlow
,而只是一个Flow
。因此,当存在StateFlow
时,我无法获得最新/当前值。
无论如何,在某个时刻,我需要Flow
中的最新值。由于这一点不在ViewModel
中,而是在一些用例实现中,所以我不能简单地执行stateIn
,并在ViewModel
处于活动状态时一直保持ViewModel
中的最新值——否则我必须将该值传递给所有用例。事实上,在用例I中,触发网络刷新,导致在StateFlow
上以及因此在mappedFlow
上发射新值。
在用例中,我有CoroutineScopes
。所以我想出了
suspend fun <T> Flow<T>.getState(): T {
return coroutineScope {
val result = stateIn(
scope = this
).value
coroutineContext.cancelChildren()
result
}
}
如果不使用coroutineContext.cancelChildren()
,该方法将永远不会返回,因为coroutineScope
会阻塞调用程序,直到所有子协同程序都完成为止。由于stateIn
从未完成,我手动取消了所有子项。
显然这是一件坏事。
但是我怎样才能更好地解决这个问题呢?在我看来,问题是由StateFlow
映射引起的,该映射导致了常规的Flow
实例。
是的,您只需要在流上调用first()
。由于它由StateFlow上游支持,first()
调用将获得该支持StateFlow的当前值,通过下游运算符进行的任何转换来运行它,并返回该值。
这有效地为您带来了与上述尝试相同的结果。
不利的一面是,所有下游运营商都必须运行,因此成本可能很高。
只有当存在上游StateFlow时,这才有可能。否则,您就无法检索到最新值的概念。
不过,我会质疑你是否需要获得最新价值。通常,您收集流,因此您已经在使用当前值。流量用于反应式编程。