hi.. i probably just need a refresher.. but how wo...
# coroutines
n
hi.. i probably just need a refresher.. but how would i manage launching 1 coroutinesfor each entry in a list coming fro ma stateflow? and relaunching them as the stateflow changes ?
k
Copy code
val flow: StateFlow<List<...>> = ...
flow.collectLatest { list ->
  coroutineScope {
    list.forEach { item -> 
      launch { item.doSomething() }
    }
  }
}
n
thanks
👍 1
r
This will collect each state flow item and wait for each launched task to complete before accepting the next which may mean they are conflated
stateFlow.collect { it.forEach { launch { task() } } }
n
i was missing the bit about collectLatest cancelling the previous one
r
ah sorry I missed that 🙂
k
stateFlow.collect
will also conflate because state flow is always conflated for slow collectors
r
yep - you'd need to buffer
n
my previous code looked like so using just a List<>
Copy code
decks.forEach {
    it
        .doThing()
        .launchIn(flowScope)
}
r
I misunderstood the relaunching, I didn't realise you'd want to cancel on a new emission, I just flagged the conflation as a warning
n
so.. if both collect and collectlatest conflate.. how would i cancel jobs launched inside of it properly before launching them again ?
k
collectLatest
will conflate less than
collect
.
The former does not exert backpressure, the latter does
You’d run into conflation with
collectLatest
when you change the state of a state flow multiple times before it has a chance to emit those changes to flow collectors
Eg.
Copy code
val sf = MutableStateFlow(0)
sf.value = sf.value + 1
sf.value = sf.value + 1
sf.value = sf.value + 1
In this scenario, you’re not guaranteed to get delivered
0, 1, 2, 3
because those updates might happen quicker than coroutine dispatch can occur. This happens regardless of the mechanism by which you collect this state flow.
n