[RxJava] debounce vs throttle 함수 차이점 비교

2021. 9. 8. 22:00Android

반응형

쓸 때마다 헷갈리는 debounce, throttle...

이번 기회에 확실히 정리해 두고, 저와 같이 헷갈리시는 분들을 위해 공유합니다. 

직접 테스트도 해보니 이해 쏙쏙 

 

목차

 


debounce 함수

public final Observable<T> debounce(long timeout, @NonNull TimeUnit unit, @NonNull Scheduler scheduler) {
	Objects.requireNonNull(unit, "unit is null");
	Objects.requireNonNull(scheduler, "scheduler is null");
	return RxJavaPlugins.onAssembly(new ObservableDebounceTimed<>(this, timeout, unit, scheduler));
}

 

특정 시간(위에서 timeout 값)이 지난 후 제일 마지막으로 들어온 이벤트만 발생하도록 하는 함수. (말로 설명하기가 너무 어렵다!)

 

예시로 이해를 돕자.

특정 시간(timeout) 값이 5초라고 가정하고 위 그림을 설명해본다.

 

❤️이벤트가 들어오고, 그 이후 아무런 인풋이 없는 상태로 5초가 지났다. => ❤️이벤트 발생!

💛이벤트가 들어오고, 2초가 지날 때쯤 💚이벤트가 새로 들어왔다.

그럼 💚가 들어온 기준으로 5초 타이머가 새로 시작한다! 그 이후 아무런 인풋이 없는 상태로 5초가 지났다. => 💚이벤트 발생!

💙이벤트가 들어오고, 그 이후 아무런 인풋이 없는 상태로 5초가 지났다. => 💙이벤트 발생!

 

이제 이해가 조금 되는가!

debounce의 특징은, 타이머가 작동하고 있을 때, 새로운 이벤트가 들어오면 타이머는 리셋된다!

 


throttle 함수 

public final Observable<T> throttleLast(long intervalDuration, @NonNull TimeUnit unit) {
    return sample(intervalDuration, unit);
}
    
public final Observable<T> throttleLast(long intervalDuration, @NonNull TimeUnit unit, @NonNull Scheduler scheduler) {
	return sample(intervalDuration, unit, scheduler);
}

RxJava에서 throttle 함수는 위와 같이 2종류가 있고, 개념은 굉장히 쉽다!

이벤트 발생이 일정 간격(intervalDuration)으로 일어난다. 그래서 위 함수를 보면 파라미터명이 intervalDuration(간격 시간)인 것!

throttleFirst

새로운 이벤트가 들어온 후, 일정한 시간 간격(intervalDuration) 이 지난 후에 해당 간격 중 가장 처음 들어온 이벤트를 발생시킨다. 

https://raw.githubusercontent.com/wiki/ReactiveX/RxJava/images/rx-operators/throttleFirst.png

 

예시로 이해를 돕자.

특정 시간(timeout)값이 5초라고 가정하고 위 그림을 설명해본다.

 

❤️이벤트가 들어오고 => ❤️이벤트 발생! 그 이후 아무런 인풋이 없는 상태로 5초가 지났다.

💛이벤트가 들어오고 => 💛이벤트 발생! 그 후 2초가 지날때쯤 💚이벤트가 새로 들어왔다. 그 이후 3초가 지났다. (throttleFirst 이기 때문에 이후에 들어온 초록이는 무시당함)

💠(하늘색하트가 없어서 요 아이로 대체..)이벤트가 들어오고 => 💠이벤트 발생! 그 후 3초가 지나고💙이벤트가 들어왔다. (파랑이 무시당함)

💜이벤트가 들어오고 => 💜이벤트 발생! 

 

 

throttleLast

새로운 이벤트가 들어온 후, 일정한 시간 간격(intervalDuration) 이 지난 후에 해당 간격 중 가장 마지막으로 들어온 이벤트를 발생시킨다. 

https://raw.githubusercontent.com/wiki/ReactiveX/RxJava/images/rx-operators/throttleLast.png

 


debounce vs throttle 비교 테스트 

조건

아래와 같이 0초부터 시작해서 2초 간격으로 input 스트림에 값을 넣는다. 

즉, for 문이 다 돌면 input 에는 아래의 값이 쌓여 있을 것이다.

=> [ "0초 후", "2초 후", "4초 후", ... , "20초 후" ]

val input = BehaviorSubject.create<String>()

for (i in 0..10) {
	val text = "${i * 2}초 후"
	input.onNext(text)

	Thread.sleep(2000L)
}

그리고 debounce, throttle 에서의 타이머 또는 간격 시간은 5초로 설정.

 

debounce 결과

호호.. 결과 심플...

   input.debounce(5000L, TimeUnit.MILLISECONDS, Schedulers.computation())
            .subscribeOn(Schedulers.computation())
            .subscribe {
                println("LOG>> debounce result : $it")
            }

debounce(5000L, TimeUnit.MILLISECONDS) 실행 결과

 

20초 만 찍힌 이유는?!

위에서 설명했듯이, debounce 는 새로운 이벤트가 들어오면 타이머를 새로 리셋하는데,
이벤트가 들어오는 간격은 2초이고, debounce 타이머는 5초이니 이벤트가 들어올 때마다 타이머가 계속 리셋되는 것!! (아래 그림 참고)

 

위와 같은 결과가 나온 이유를 그림으로 풀이해봤다. 👇👇

 

throttleLast 결과

input.throttleLast(5000L, TimeUnit.MILLISECONDS, Schedulers.computation())
            .subscribeOn(Schedulers.computation())
            .subscribe {
                println("LOG>> throttle result : $it")
            }

throttleLast(5000L, TimeUnit.MILLISECONDS) 실행 결과

 

위와 같은 결과가 나온 이유를 그림으로 풀이해봤다. 👇👇

 

 

throttleFirst 결과

input.throttleFirst(5000L, TimeUnit.MILLISECONDS, Schedulers.computation())
            .subscribeOn(Schedulers.computation())
            .subscribe {
                println("LOG>> throttle result : $it")
            }

throttleFirst(5000L, TimeUnit.MILLISECONDS) 실행 결과

 


 

간단 요약

  • debounce, throttle 함수 모두 일정 시간 동안에 발생한 마지막 이벤트를 발생시키는 개념.
  • debounce 의 경우, 새로운 이벤트가 들어올 때마다 타이머를 리셋시켜서, 이벤트가 들어온 후 특정 시간이 지났을 때 해당 이벤트를 발생시킴.
  • throttle의 경우, 이벤트가 들어온 후 일정 시간 간격마다 이벤트가 발생한다. 일정 시간 간격 동안 가장 먼저 들어온 이벤트를 발생시키거나, 가장 마지막으로 들어온 이벤트를 발생시키거나
  • TL;DR; 위에 있는 그림 설명들을 보자. 그림을 보면 깔끔하게 이해된다! 

Reference

http://reactivex.io/documentation/operators/debounce.html 

http://reactivex.io/documentation/operators/debounce.html#collapseRxSwift 

https://proandroiddev.com/throttling-in-rxjava-2-d640ea5f7bf1  

 

 

반응형