Debounce vs Throttle

나고수·2022년 1월 23일
0

1일1공부

목록 보기
4/68
post-custom-banner

debounce : 이벤트가 발생 한 후 인터벌 n 초 동안 아무 다른 이벤트가 일어나지 않아야 그 이벤트가 실행된다. 만약 n초 사이에 다른 이벤트가 발생하면 그 때부터 다시 n초가 리셋되서 카운팅된다.
만약 인터벌이 5초이면) 이벤트 실행 후 5초 간 아무 이벤트가 일어나지 않아야 그 이벤트가 실행된다.
만약 5초 전에 다른 이벤트가 발생하면, 그 때부터 다시 5초가 카운팅된다.
A ---3sec---> B ----2sec---> C ---5sec---> D ---2sec---> E---5sec--->
여기서는, c와 e만 발생 후 5초간 아무 이벤트가 없었기 때문에 이벤트가 발생한다.

throttleFirst : 만약 인터벌이 5초이면) 5초간 실행된 이벤트 중 가장 첫번째 이벤트가 실행된다. debounce와 다른 점은, a 가 발생되고 3초 후 b 가 발생됐다고 해서 새로 5초가 카운팅 되는 것이 아님.
A---3sec---> B---3sec--->C
debounce 라면 B에서 다시 5초가 리셋 되었겠지만, throttleFirst에서는, B와 C 사이의 5초에서, 그 중 가장 첫번째 발생한 이벤트인 A가 실행된다.

throttleLast : 만약 인터벌이 5초이면) 5초간 실행된 이벤트 중 가장 마지막 이벤트가 실행된다.
A ---3sec---> B---3sec--->C
throttleLast에서는, B와 C 사이의 5초에서, 그 중 가장 마지막에 발생한 이벤트인 B가 실행된다.

debounce 와 throttle 둘다 search / 버튼 클릭 후 api를 요청 할 때 적절히 사용하면 api 요청 남용을 막을 수 있다.

fun <T> throttleFirst(
   skipMs: Long = 300L,
   coroutineScope: CoroutineScope,
   destinationFunction: (T) -> Unit
): (T) -> Unit {
   var throttleJob: Job? = null
   return { param: T ->
       if (throttleJob?.isCompleted != false) {
           throttleJob = coroutineScope.launch {
               destinationFunction(param)
               delay(skipMs)
           }
       }
   }
}
fun <T> throttleLatest(
    intervalMs: Long = 300L,
    coroutineScope: CoroutineScope,
    destinationFunction: (T) -> Unit
): (T) -> Unit {
    var throttleJob: Job? = null
    var latestParam: T
    return { param: T ->
        latestParam = param
        if (throttleJob?.isCompleted != false) {
            throttleJob = coroutineScope.launch {
                delay(intervalMs)
                latestParam.let(destinationFunction)
            }
        }
    }
}
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)
        }
    }
}

소스코드는 스택오버플로우에서 훔쳐오기...
이 블로그에 그림을 보면 이해가 잘 간다

profile
되고싶다
post-custom-banner

0개의 댓글