kotlinx.coroutines icon indicating copy to clipboard operation
kotlinx.coroutines copied to clipboard

Undispatched `collectLatest`

Open dovchinnikov opened this issue 2 years ago • 2 comments

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

dovchinnikov avatar Mar 14 '23 14:03 dovchinnikov

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.

dovchinnikov avatar Feb 15 '24 15:02 dovchinnikov