사이드 프로젝트 개발 중, 코드리뷰로 버튼 input 이벤트에 대해
" throttle 말고 debounce 를 사용한 이유를 알 수 있을까요 ?! "
라는 리뷰를 받았었다.
음 .. 그러게요? 나 왜 debounce를 사용했지? throttle과 기능적 차이점은 어떤 게 있을까?
잊지 않기 위해 글로 남겨보고자 한다.
debounce
관찰 가능한 항목을 다른 항목을 방출하지 않고 특정 시간대를 경과한 경우에만 방출합니다.
only emit an item from an Observable if a particular timespan has passed without it emitting another item.
내가 적용한 코드를 예시로 살펴보자.
ViewModel 에서 Input으로 좋아요 버튼 클릭 이벤트를 likeButtonTapped를 정의했다.
자체 QA를 진행했을 때 좋아요 버튼을 연속적으로 와다다다 탭하면 서버가 버티지 못하고 터지는 이슈를 발견했다 ...
그래서 더더욱 operator 적용이 필요하단 것을 느꼈다.
위와 같이 적용하면 0.3초 동안 이벤트가 없으면 그때 이벤트가 방출되도록 하는 것이다.
더 쉽게 이해를 해보자면,
tap -> 0.3초 지남 -> 이벤트 방출 OK
tap -> 0.1초 후 -> tap -> 0.2초 후 -> tap -> 0.3초 지남 -> 이벤트 방출 OK
이런 데이터의 흐름인 것이다.
즉, input이 들어오는 대로 다 흐름이 연결되는 것이 아닌, 개발자가 코드로 지정한 시간이 흐르면 그때 이벤트가 방출되는 것!
throttle
지정된 기간의 순차적 시간 동안 소스 Observable이 방출하는 첫 번째 및 최신 항목을 방출하는 Observable을 반환합니다. 이 연산자는 dueTime보다 짧은 시간 동안 두 개의 요소가 방출되지 않도록 합니다.
Returns an Observable that emits the first and the latest item emitted by the source Observable during sequential time windows of a specified duration. This operator makes sure that no two elements are emitted in less then dueTime.
위와 마찬가지로 내가 작성한 코드를 예시로 살펴보자.
이번엔 ViewModel에서 Output으로 정의된 뒤로 가기 버튼의 이벤트를 backButtonEnabled로 정의했다.
위와 같이 적용하면 backButtonEnabled 이벤트가 방출이 되고 3초 동안에 최초로 방출한 이벤트 1개만을 메인쓰레드에서 돌린다는 의미인 것이다.
throttle의 인자 중 2번째 인자인 latest가 중요하다!
latest는 정해진 시간 동안에 방출된 이벤트들 중 마지막 이벤트도 방출해 ? 아님 방출하지마 ? 를 정해주는 Boolean이다.
latest: true 일 때 -> 마지막 이벤트도 방출해줘 !
latest: false 일 때 -> 마지막 이벤트는 방출하지마 !
그래서 어떻게 적용할건데?
나름 차이점을 많이 찾아보면서 아티클도 많이 읽어보고 판단했던 바에 대해 작성했었다.
debounce는 특정 기간동안 마지막 이벤트만을 방출하는 operator이다. 그렇기 때문에 버튼 이벤트와 같이 와다다다(?) 이슈가 발생할 수 있는 이벤트에는 debounce가 조금 더 적합할 것이라고 판단했다.
또한, throttle은 이벤트들 중 첫번째 이벤트만을 구독하기 때문에 무한스크롤과 같은 이벤트에 더 적합하다고 판단했다. 유저가 스크롤을 충분히 한 뒤에서야 데이터가 불러와지는 것보단, 스크롤을 하고 있는 도중에 데이터가 불러와지는 게 더 자연스러운 UX라고 판단되었다.
이와 같은 내용이 저 이미지에 있는 medium 아티클에 있었고 너무 공감이 되었다!
앞으로는 이 두 operator의 기능을 헷갈리지 않고 활용할 수 있도록 ! 까먹지 말자 !
+) 진짜 헷갈린다면 두 operator의 사전적 정의를 생각해보면 더 이해가 간다 !
throttle: 목을 조르다.
debounce: 여러 이벤트가 발생할 때, 이들을 하나의 그룹으로 묶어서 처리하다. (전자공학용어)