Tim Malseed
10/26/2022, 12:26 AMTim Malseed
10/26/2022, 12:26 AMval myStateFlow = MutableStateFlow<Int>(1)
fun updateStateFlow() {
myStateFlow.value = 2
myStateFlow.value = 3
}
@Test
fun testStateFlow() {
assertEquals(1, myStateFlow.value)
updateStateFlow()
assertEquals(2, myStateFlow.value) // Obviously this will fail
assertEquals(3, myStateFlow.value)
}
james
10/26/2022, 12:40 AMTim Malseed
10/26/2022, 12:48 AMTim Malseed
10/26/2022, 12:49 AMval collectJob = launch(UnconfinedTestDispatcher()) { myStateFlow.collect() }
But I don’t recall or understand this!jw
10/26/2022, 12:56 AMUnconfined
dispatcher. This will ensure that your collector coroutine can be started in the same stackframe as the one updating the value.
• A non-suspending collector. This ensures that there's no possibility for the upstream to conflate updates.
This is what Turbine does. It also uses UNDISPATCHED
to launch its coroutine to ensure collection starts synchronously rather than upon first suspension.jw
10/26/2022, 1:01 AMval values = mutableListOf<Int>()
launch(UNDISPATCHED, Unconfined) {
myStateFlow.collect { values += it }
}
assertEquals(listOf(1), values)
updateStateFlow()
assertEquals(listOf(1, 2, 3), values)
Tim Malseed
10/26/2022, 1:05 AMjw
10/26/2022, 1:10 AMreceive()
to read values. And that is also the mechanism that will suspend waiting for new values to arrive.