https://kotlinlang.org logo
#coroutines
Title
# coroutines
e

Erik

09/08/2020, 1:30 PM
With flows it's simple to
debounce
input. I'd like to know if some value is currently being debounced (and I'd like to know the value), so that I don't have to wait for it to be collected downstream. How would I do that?
Use case: A user enters text input, which generates a stream of events, which are debounced, e.g. for 250 ms. A user can also press a 'save' button, on which I'd like to save the latest text state. However, due to the debounce operator, I'd have to wait for up to 250 ms (assuming that the user can quickly press the save button after changing the text for the last time). So, for the save button action, I'd like to just take the non-debounced last value in the flow.
s

streetsofboston

09/08/2020, 1:53 PM
Update your text-state ‘immediately’, i.e. without using any debouncing. Only debounce what is sent to the API that needs the debouncing. Then your ‘Save’ button can just using the text-state which will be up-to-date
e

Erik

09/08/2020, 2:00 PM
Thanks. Yes, I indeed figured that I'd need to keep track of state somewhere before the debounce
Trouble is: I keep UI state after the debounce 😐
s

streetsofboston

09/08/2020, 2:06 PM
I think you may need to change that to keep UI state before any debounce. Merge any result from the ‘debounced’ API request into the UI state.
e

Erik

09/08/2020, 3:32 PM
I'll try to push the debounce as far downstream in my state system as I can, so that other state consumers remain upstream
d

Daniele Segato

09/08/2020, 3:50 PM
you would do this in RxJava with
throttleFirst
I believe. Isn't there an operator like this for Flow?
Copy code
fun <T> Flow<T>.throttleFist(windowDuration: Long): Flow<T> = flow {
    var windowStartTime = System.currentTimeMillis()
    var emitted = false
    collect { value ->
        val currentTime = System.currentTimeMillis()
        val delta = currentTime - windowStartTime
        if (delta >= windowDuration) {
            windowStartTime += delta / windowDuration * windowDuration
            emitted = false
        }
        if (!emitted) {
            emit(value)
            emitted = true
        }
    }
}
this should work as a throttleFirst operator (implementation linked here: https://github.com/Kotlin/kotlinx.coroutines/issues/1446)
19 Views