Chapter 12 : UseCase09 - debounce
Let us now work on time-based control
debounce() waits for a quiet period before emitting a value.
If new values keep arriving quickly, it keeps resetting the timer. Only when emissions stop for a specified duration does the latest value get emitted.
REAL STOCK SCENARIO
A user types into a search box :
H
HE
HEL
HELI
HELIO
HELIOS
Say we have a list of 6000 stocks. Do we want to filter 6000 stocks on every keystroke?
Certainly not. We wait until the user stops typing. That is debounce()
What debounce() does
If values arrive faster than the debounce duration, they are ignored.
Only the latest value after a pause is emitted.
Let us checkout a working example from our stocks list.
package org.kotlinflowlearner.stockflow.usecases.uc09
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.flow.flow
/**
* UC09DebounceStockSearch demonstrates how debounce()
* waits for a pause before emitting the latest value.
*/
class UC09DebounceStockSearch {
private fun simulatedSearchQueries(): Flow<String> = flow {
emit("H")
delay(100)
emit("HE")
delay(100)
emit("HEL")
delay(100)
emit("HELI")
delay(100)
emit("HELIO")
delay(100) //this pause is shorter than 500ms
emit("HELIOS")
delay(600) //this pause is longer than the debounce window of 500ms defined below
}
fun debouncedSearch() : Flow<String> = simulatedSearchQueries().debounce(500)
}
package org.kotlinflowlearner.stockflow.usecases.uc09
import kotlinx.coroutines.runBlocking
fun main(){
runBlocking {
val useCase = UC09DebounceStockSearch()
useCase.debouncedSearch().collect{
query -> println("Processing search for: $query")
}
}
}
The output produced is
Processing search for: HELIOS
WHAT IS ACTUALLY HAPPENING
"H" is emitted.
Debounce starts a 500ms timer.After 100ms, "HE" arrives.
The previous timer is cancelled. A new 500ms timer starts for "HE".After 100ms, "HEL" arrives.
Cancel timer again. Start new timer.Same for "HELI".
Same for "HELIO".
Same for "HELIOS".
Now finally:
After emitting "HELIOS", we wait 600ms.
That exceeds 500ms. So the debounce timer completes. Now "HELIOS" is emitted downstream.
Key Insight
Let’s understand what debounce(500) really means in the above example.
It means:
“After receiving a value, wait 500 milliseconds.
If no new value arrives during that time, emit it.
If a new value arrives before 500 milliseconds, cancel the previous wait and start again.”
So the timer is attached to each emission.
debounce() is time-based filtering. It prevents noisy rapid emissions from triggering unnecessary processing.
Why does debounce() reset?
Because debounce is designed to detect silence. It does not care about how many values come.
It only cares about - Has there been a pause long enough?
If not, it keeps postponing emission.
Why This Matters in Stock Analysis
Real scenarios:
Stock symbol search
Country filtering
Market cap range sliders
Price filters
Dashboard filters
You do not want to recompute analytics for every tiny input change.
You wait for stability.