Undispatched `collectLatest`
Use case
This a contrived example.
class MyCheckBox(cs: CoroutineScope, initialValue: Boolean): JCheckBox() {
private val vm = MutableStateFlow(initialValue) // view model
init {
[email protected] = initialValue
cs.launch {
vm.collectLatest {
[email protected] = it
}
}
}
}
Instead of duplicating the logic, I'd like to write a single lambda, which would react on VM changes. The applying of VM state to the UI could take a while, and can suspend. We have a case, where some loading indication happens, then the final state is shown, but if the state is changed during loading, it should be kept on screen to avoid flickering.
It's currently possible to collect in an undispatched coroutine, if the value is available, then it's applied immediately during construction of the UI component.
cs.launch(start = CoroutineStart.UNDISPATCHED) {
vm.collect {
[email protected] = it
}
}
But with collectLatest, the block is always dispatched to be executed later.
API-shape
I think this issue should be considered together with #3679 and #3533.
Since collectLatest launches new coroutines, it should accept start and context parameters somehow, and it should accept CoroutineScope lambda to be consistent with launch/async
I think UNDISPATCHED should be used to fix #1825 instead ATOMIC start (which forces dispatch).
https://github.com/Kotlin/kotlinx.coroutines/pull/1829/commits/15112a6c71829adb9a073aca1f03f1fd3afb8266
This way, an additional parameter is not needed in the API, and collectLatest will behave like collect w.r.t. to dispatch logic.
kotlinx.coroutines.flow.internal.ChannelFlowTransformLatest#flowCollect hints that dispatch is not needed