Skip to content

Instantly share code, notes, and snippets.

@macsystems
Last active May 14, 2024 15:50
Show Gist options
  • Save macsystems/ea80b9d3a2db04f884bcb46469788878 to your computer and use it in GitHub Desktop.
Save macsystems/ea80b9d3a2db04f884bcb46469788878 to your computer and use it in GitHub Desktop.
Flow debounce operator which debounces matching events and also ignores when it gets emited multiple times
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.channelFlow
import kotlinx.coroutines.launch
import kotlin.time.Duration
/**
* Debouncing when predicate is [true]
*/
fun <T> Flow<T>.debounce(
debounceTime: Duration,
predicate: (T) -> Boolean
): Flow<T> = channelFlow {
var debounceJob: Job? = null
var isDebouncing = false // Flag to track if debounce job is active
collect { value ->
if (predicate(value)) {
if (!isDebouncing) { // Only start debounce if not already debouncing
isDebouncing = true
debounceJob?.cancel() // Cancel the previous debounce job
debounceJob = launch {
delay(debounceTime) // Wait for the specified duration
isDebouncing = false
send(value) // Send the value downstream after the debounce time
}
}
} else {
if (!isDebouncing) { // If not debouncing, immediately emit non-predicate matching events
send(value)
}
}
}
}
@macsystems
Copy link
Author

            viewModel.journey.asFlow().debounce(debounceTime = 2.toDuration(DurationUnit.SECONDS)) { something ->
               something.specific == debouceThis
            }.collect {
                callSomeMethod(something)
            }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment