无法从Flow获取以前发出的值。
class TestActivity: ComponentActivity() {
...
private val flowA = MutableStateFlow(0)
private val flowB = MutableStateFlow("")
init {
flowB.onEach { Log.d("flowtest", "test - $it") }
.launchIn(lifecycleScope)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
flowB.value = "1"
flowB.value = "2"
flowB.value = "3"
flowA.map { "ignore" }
.onEach {
flowB.value = "4"
flowB.value = "5"
flowB.value = "6"
}
.launchIn(lifecycleScope)
flowA.value = 0
...
}
期待
试验-1
试验-2
试验-3
试验-4
试验-5
测试-6
结果
试验-1
试验-2
试验-3
测试-6
"心流"的概念有什么缺失?
如何获取以前的发射值?
2条答案
按热度按时间ufj5ltwl1#
这只是一个猜测,因为我并不想费心去做一个项目并测试它。
首先,关于StateFlow有两件事需要记住。
1.它被限制为历史记录1。它只能向新订阅者重播单个值。
1.它是合并的,这意味着如果收集器的速度慢于输入的排放量,收集器将错过一些排放值,而只得到最新的值。
因此,查看您的代码,乍一看,您可能只会看到:
这是因为您是在主线程上发射,并在主线程上收集,所以无论何时您在一行中有多个StateFlow值更改,我希望只有在方法中调用的最后一个值“保留”,因为收集器必须等待轮到它的主线程被放弃,然后才能收集它的下一个值。
那么,为什么会出现
1
和2
呢?实际上,
lifecycleScope
并没有使用Dispatchers.Main
,它使用Dispatchers.Main.immediate
,Dispatchers.Main.immediate
的行为稍有不同。如果你已经在Main
线程上,immediate
版本会立即运行挂起的代码,而不是先让位给其他协程。所以,我的理论是,当你在主线程上更改值时,但是你在
Dispatchers.Main.immediate
上收集flowB
的onEach
,所以每当你向flowB
发出一个值时,它就有机会立即运行它的onEach
。但是,提醒一下,我实际上还没有用
immediate
测试流来检验这个假设,这只是我能想到的唯一解释这个行为的原因。要自己检验这个理论,你可以在两个地方都使用launchIn(lifecycleScope + Dispatchers.Main)
,看看1
和2
是否消失了。k5ifujac2#
实际上,这段代码有问题,因为value属性是stateFlow属性,而不是sharedFlow属性。另外,如果收集器和订阅器在同一个协程中,则无法在收集数据后向stateFlow添加值。因此,正确的代码应为:
和结果将是:3
因为***stateFlow只保留最后发出的一个***
如果你想得到所有的值,你可以像这样使用SharedFlow:
您可以查看文档以获取更多信息SharedFlowStateFlow