Skip to content

Instantly share code, notes, and snippets.

@Sar777
Forked from elizarov/Debounce.kt
Created February 11, 2019 08:17
Show Gist options
  • Save Sar777/faf84960bd884b5e76416e024e6117ab to your computer and use it in GitHub Desktop.
Save Sar777/faf84960bd884b5e76416e024e6117ab to your computer and use it in GitHub Desktop.
Debounce
import kotlinx.coroutines.experimental.DefaultDispatcher
import kotlinx.coroutines.experimental.channels.ReceiveChannel
import kotlinx.coroutines.experimental.channels.consumeEach
import kotlinx.coroutines.experimental.channels.produce
import kotlinx.coroutines.experimental.delay
import kotlinx.coroutines.experimental.runBlocking
import kotlin.coroutines.experimental.CoroutineContext
fun <T> ReceiveChannel<T>.debounce(
wait: Long = 300,
context: CoroutineContext = DefaultDispatcher
): ReceiveChannel<T> = produce(context) {
var nextTime = 0L
consumeEach {
val curTime = System.currentTimeMillis()
if (curTime < nextTime) {
// not enough time passed from last send
delay(nextTime - curTime)
var mostRecent = it
while (!isEmpty) { mostRecent = receive() } // take the most recently sent without waiting
nextTime += wait // maintain strict time interval between sends
send(mostRecent)
} else {
// big pause between original events
nextTime = curTime + wait // start tracking time interval from scratch
send(it)
}
}
}
fun main(args: Array<String>) = runBlocking {
val channel = produce<Int> {
(0..100).forEach {
println("send")
send(it)
delay(100)
}
}
channel.debounce().consumeEach { println("Yay!") }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment