I'm looking at the implementation of `Flow.debounc...
# coroutines
o
I'm looking at the implementation of
Flow.debounce()
and I saw it's quite complex. Now thinking about it, can't debounce be simplified to the following implementation?:
Copy code
fun Flow.debounce(timeoutMillis: Long) = transformLatest {
    delay(timeoutMillis)
    emit(it)
}
m
no. because debounce isnt cummulative
o
What does that mean?
m
imagine you are tying a word, and you stop at the middle. Debouncing 200ms means when you stop typing, after 200ms there is an emission. with your implementation, it will wait 200ms x nr of characters
oh nvm, its transform latest so prbaly gets cancelled
o
@ephemient well, isn't that also how the current implementation is? Because thats how debounce is meant to work
e
hmm, I thought it was time since the first emission, but I gave it a test and I remembered wrong
o
Nope its time since the last emission
m
no. debounce means, within an interval, send the last event
if the time has not passed when a new event comes, it should reset
o
So, is it correct that my implementation of debounce results in the same behaviour as stdlib's implementation?
Because it sure looks like it
m
well, maplatest will cancel the previous event, so apparantly it might
but probably its too costly, thats why the custom impl. i dont know
o
Yeah, potential performance optimization is the only reason I can think of that clarifies the current impl
u
Shouldn’t you be waiting for 200ms silence and then pick the latest emission? I don’t see the point in delaying emission of an item after it is already determined to be emitted.
o
@uli I dont understand your question; what you described is the point of debounce
u
Let’s say, you have the following sequence of events:
Copy code
000ms: 1
050ms: 2
260ms: 3
then I’d expect to see the following emitted from a debounce:
Copy code
250ms: 2 // No upstream event for 200ms since `2` was received -> emmit `2`
460ms: 3 // No upstream event for 200ms since `3` was rexeived -> emmit `3`
With your code you would probably get:
Copy code
200ms: 1 // Take first event (`1`) and delay 200ms before emitting
400ms: 2 // Take last event before 200ms (`2`) and delay 200ms before emitting
600ms: 3 // Take last event before 400ms (`3`) and delay 200ms before emitting
And the question is, why would you pic event
1
immediately but then delay for 200ms before emitting?
From the reactiveX docs (http://reactivex.io/documentation/operators/debounce.html)
Copy code
only emit an item from an Observable if a particular timespan has passed without it emitting another item
My mistake. I was confused about how transformLatest works. For some reason I thought it was just conflating. Your code should work.