Unexpectedly, but it seems, this question was never asked before (at least I didn't find it).
So, if we have some search EditText
and want to send search requests to server, when user inputs text. Strait approach will lead to the case, when we send request to server for each typed symbol. To escape this case, we need to add some logic to wait until user stops typing search query. My question is applicable for app with coroutines.
If we use coroutines, for now there is two ways to implement user input delay. First is to use coroutines.delay
function, it is presented here. Its main idea is to launch and delay coroutine
fun <T> debounce(
waitMs: Long = 300L,
coroutineScope: CoroutineScope,
destinationFunction: (T) -> Unit
): (T) -> Unit {
var debounceJob: Job? = null
return { param: T ->
debounceJob?.cancel()
debounceJob = coroutineScope.launch {
delay(waitMs)
destinationFunction(param)
}
}
}
Second way is to use new function flow.debounce
, it is presented here. Its main idea is we make flow from EditText
input and then apply debounce to it
@ExperimentalCoroutinesApi
@CheckResult
fun EditText.textChanges(): Flow<CharSequence?> {
return callbackFlow {
checkMainThread()
val listener = doOnTextChanged { text, _, _, _ -> trySend(text) }
awaitClose { removeTextChangedListener(listener) }
}.onStart { emit(text) }
}
editText.textChanges()
.debounce(300)
.onEach { ... }
.launchIn(lifecycleScope)
My question is about differences in this two approaches (except they use different technologies) and about advantages and disadvantages of both of them. Hope someone is able to clarify the difference.