⛹️‍♂️

kotlinx.coroutines.Jobで処理をdebounceさせる(間引く)

2021/02/01に公開

デバウンス

  • イベント処理の間引きを行うことまたはその仕組みのこと

リアルタイムに通知しなければいけないけど、 処理回数が大量すぎる際に、一定の時間内に入力された最終的な入力結果だけが欲しい時などに便利です。

/**
 * 指定したmilli秒に応じて、処理をdebounceさせる拡張
 *
 * @param delayMillis 遅延させる秒数
 * @param coroutineScope 実行するcoroutineScope
 * @param coroutineDispatcher スレッドの指定
 * @param invokeAction 実行する関数
 */
fun <T> debounce(
        delayMillis: Long,
        coroutineScope: CoroutineScope,
        coroutineDispatcher: CoroutineDispatcher,
        invokeAction: (T) -> Unit): (T) -> Unit {
    var debounceJob: Job? = null
    return { param: T ->
        debounceJob?.cancel()
        debounceJob = coroutineScope.launch(coroutineDispatcher) {
            delay(delayMillis)
            invokeAction(param)
        }
    }
}

ex.) 引数なし

val debounceUpdateData: () -> Unit = debounce(200, viewModelScope, Dispatchers.Default) {
               doTask()
}

ex.) 引数あり

val debounceUpdateData: (/**itに渡したいクラス**/) -> Unit = debounce(200, viewModelScope, Dispatchers.Default) {
                //更新処理
                doTask(it)
}

Flowでこの機能は用意されてるみたいですが、ワンショットで戻り値など特に必要でもない場合はこんな感じで良さそうです。

https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/
https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/debounce.html

Discussion