molecule icon indicating copy to clipboard operation
molecule copied to clipboard

Debouncing state emissions

Open TheKeeperOfPie opened this issue 2 years ago • 4 comments

I'm trying to migrate

val data = snapshotFlow { buildFromState() }.debounce(1.seconds)
...
data.collectAsState(null)

to remove the view side default null value.

But there's no easy way to debounce in Molecule. I think the closest you can get would be

val debouncedFlow = snapshotFlow { buildFromState() }.debounce(1.seconds)
val state = scope.launchMolecule { 
    debouncedFlow.collectAsState(buildFromState()).value
}

but this moves from Compose (the actual state) -> Flow (snapshotFlow) -> Molecule -> Compose (collectAsState) -> Compose UI, which is very inefficient compared to reading the state directly inside Molecule. It also requires calling buildFromState() redundantly.

If there was a way to control/throttle the recomposition timing in Molecule, then I could try and make it only recompose every second or when the debounce concluded.

TheKeeperOfPie avatar Nov 28 '23 00:11 TheKeeperOfPie

@Composable
fun <T> debounce(value: T, duration: Duration): T {
  // ????
}

This can't be implemented on a StateFlow, but it should be implementable in compose

jingibus avatar Nov 28 '23 00:11 jingibus

I think that perhaps we want to consider accepting a frame clock even when using immediate mode. This would allow you to use an at-most-once-a-second frame clock either directly, or with the immediate mode. It would apply the back pressure to the recomposition rather than allowing it to run unbounded simply to discard its results.

JakeWharton avatar Nov 28 '23 00:11 JakeWharton

I think that perhaps we want to consider accepting a frame clock even when using immediate mode.

I would think this would be equivalent to using the frame clock directly. What advantage does this give us over providing some utility code to create frame clocks from Flow<Unit>, or something similar?

jingibus avatar Nov 28 '23 00:11 jingibus

I was thinking that there was some advantage to still using the immediate mode such as immediately running if the period had already expired, but you're right that's just clock implementation details.

JakeWharton avatar Nov 28 '23 00:11 JakeWharton