Mark
11/25/2020, 8:48 AMcollect()
vs collectLatest()
: I see the docs for collectLatest()
say: when the original flow emits a new value, action block for previous value is cancelled.
But specifically for StateFlow
just about all the examples I see use collect()
. So I’m wondering if the decision whether to use collect()
or collectLatest()
can/should be made on the basis of the nature of the action block (for example, an action block of non-suspending code I suppose the choice is irrelevant - or more generally, is there a problem with cancelling the action block before completion) or whether the nature of StateFlow
also impacts the decision somehow?wasyl
11/25/2020, 9:16 AMStateFlow
you’d usually be concerned about the latest value only, so collectLatest
would be typically correct.
I think this is the correct answer:
should be made on the basis of the nature of the action blockIf we’re collecting values from somewhere to show on the UI for example, you should use
collectLatest
. If you have a flow with messages that you want to show one by one (with an animation perhaps), then you should use collect
because it’s important that each emission is handledMark
11/25/2020, 9:18 AMStateFlow
since you care about all values?gildor
11/25/2020, 9:21 AMIf we’re collecting values from somewhere to show on the UI for example, you should useNot sure that such broad separation is correct, usage of collect vs collectLatest should be decided depending on nature of collect block, should it be cancelled or not UI also has different cases.collectLatest
gildor
11/25/2020, 9:24 AMwouldn’t you not be usingOf course, StateFlow has buffer with size 1, it’s possible that new value will override previous one which is not collected yetsince you care about all valuesStateFlow
wasyl
11/25/2020, 9:26 AMNot sure that such broad separation is correct,That’s what I meant, the second example with messages is also UI 🙂
wouldn’t you not be usingYep, that’s why I think usually withsince you care about all values?StateFlow
StateFlow
I’d use collectLatest
.gildor
11/25/2020, 9:30 AMMark
11/25/2020, 9:30 AMgildor
11/25/2020, 9:31 AMwasyl
11/25/2020, 9:33 AMStateFlow
represents state, and with state I’m usually concerned with the latest value only. Regular Flow
, just in my experience, represents values that are usually important individuallyMark
11/25/2020, 9:34 AMStateFlow
is really a side question. I’m currently just working out a general default strategy for when collecting StateFlow
.Mark
11/25/2020, 9:37 AMStateFlow.collectLatest
seems to be a good reasonable default. Only switch to using collect
if there is a good reason for the the action block not to be cancelled (uncommon scenario I suspect).gildor
11/25/2020, 9:37 AMMark
11/25/2020, 9:38 AMStateFlow
wasyl
11/25/2020, 9:42 AMcollectLatest
(for any flow), unless it would be incorrect to ignore a valuegildor
11/25/2020, 10:19 AMAdam Powell
11/25/2020, 4:09 PMcollectLatest
as a default without explicitly needing the cancellation behavior in that particular case is kind of silly. It introduces some rather nontrivial overhead over a collect: https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/common/src/flow/internal/Merge.kt#L13Adam Powell
11/25/2020, 4:11 PMwasyl
11/26/2020, 8:55 AM*latest
operators, then? Only use them if the work inside the action block is expensive and worth cancelling?wasyl
11/26/2020, 9:08 AMcollectLatest
doesn’t actually do anything except add the overhead, is that right? Do you mean such situation by unnecessary usage?Adam Powell
11/26/2020, 3:34 PMAdam Powell
11/26/2020, 3:36 PMAdam Powell
11/26/2020, 3:39 PMwasyl
11/26/2020, 3:43 PMcollectLatest
is less efficient even if there’s no backpressure, when collect block always completes before the next event comes? I understand collectLatest doesn’t give any benefits then, so it’s only slower than collect
?Adam Powell
11/26/2020, 4:01 PMwasyl
11/26/2020, 4:16 PMMark
11/27/2020, 8:20 AMcollectLatest
had an automatic cost, so this is really good to know. Use collect
by default.