RxSwift에서 비슷한 역할을 하는 오퍼레이터들이 있다.
그 중에서 debounce와 throttle의 차이에 대해 알아보도록 하겠다.
debounce
debounce와 throttle 둘 다 특정한 시간 텀을 두고 같은 동작이 일어나지 않게 하는 오퍼레이터라고 보면 된다.
둘의 차이를 보기 위해 둘다 버튼을 탭하는 동작에 적용을 해놓은 상태이다.
버튼을 누르면 count가 +=1 되고, 그 숫자가 Label에 반영이 되는 형태이다.
그 중에 먼저 debounce의 코드는 다음과 같다.
debounceButton.rx.tap
.debounce(.seconds(2), scheduler: MainScheduler.instance)
.bind(with: self) { owner, _ in
owner.debounceCount += 1
owner.debounceLabel.text = "\(owner.debounceCount)"
}
.disposed(by: disposeBag)
debounce는 다음과 같은 동작을 한다
버튼 탭 -> (설정한 시간동안 대기) -> count+=1
현재 dueTime 매개변수에 `.second(2)`를 통해 2초라는 시간을 정해둔 상태이다.
그 상태에서 버튼을 누르면 2초라는 시간동안 대기한 이후에 count가 올라가는 것을 볼 수 있다.
그래서 버튼을 아무리 많이 눌러도, 맨 마지막 tap 동작이 일어난지 2초 이후에 한번 반영이 된걸 볼 수 있다.
RxMarbles 그림으로 보면 다음과 같다.
여기서는 10초를 설정해둔 상태이고, 1 이벤트가 발생하고 10초 이후에 방출이 되는걸 표현했다.
2, 3, 4는 10초 이내에 발생됐기 때문에 방출이 되지 않았다가 맨 마지막에 발생한 5만 10초 이후에 방출이 된걸 볼 수 있다.
이러한 특징 때문에 debounce는 서치바나 텍스트필드에서 실시간 검색을 할 때 사용되곤 한다.
사용자가 특정 단어를 검색하기 위해 거쳐가는 순간동안 검색을 하지 않다가, 마지막 단어까지 입력된 이후로 특정 시간 이후에 검색이 되는 동작이다.
이렇게 되면 검색어를 입력하는 그 사이의 시간동안 API 요청을 줄일 수 있을것이다.
throttle
throttle 역시 button과 label이 있고, 코드는 다음과 같다.
throttleButton.rx.tap
.throttle(.seconds(2), latest: true, scheduler: MainScheduler.instance)
.bind(with: self) { owner, _ in
owner.throttleCount += 1
owner.throttleLabel.text = "\(owner.throttleCount)"
}
.disposed(by: disposeBag)
debounce와 다른점은 latest라는 매개변수가 있는데, 기본값은 true로 생략 가능하다.
이 매개변수에 대해서는 뒤에서 조금 더 알아보도록 하고, 일단 기본값으로 테스트했을 때 다음과 같은 동작이 일어난다.
버튼 탭 -> count+=1 -> 설정한 시간동안 대기
마찬가지로 dueTime에 2초의 시간을 설정해둔 상태이다.
버튼을 누르자마자 바로 count+=1이 반영이되는걸 볼 수 있다.
그리고 2초가 지난 이후에 마지막 이벤트가 다시 방출돼서 다시한번 count +=1이 반영되었다.
그리고 그 이후에 버튼을 계속 누르면 설정해놓은 시간동안 대기를 하다가 새로운 이벤트가 반영이 되는거 볼 수 있다.
latest가 true로 설정되어있다는 것은, 설정한 시간 내에 몇 번의 10번의 이벤트가 발생되었다면, 맨 처음의 1번 이벤트와, 맨 마지막에 발생한 10번 이벤트가 방출되는걸 뜻한다.
즉, 처음의 이벤트, 가장 최신에 발생한 이벤트까지 총 두 번 방출되는 설정이라고 보면 된다.
그래서 latest를 false로 설정하면 동작은 다음과 같다.
설정해놓은 시간 2초 안에 3번을 탭했는데 한 번만 반영이 된걸 볼 수 있다.
이후에 다시 버튼을 3번 탭했는데 역시 첫번째 이벤트 한번만 방출이 된걸 볼 수 있다.
RxMarbles 그림으로 보면 다음과 같다.
A이벤트가 발생하자마자 바로 방출되고, 설정한 시간내에 B, C이벤트가 발생하더라도 해당 이벤트들은 방출되지 않는다.
설정한 시간 이후에 D라는 이벤트가 발생되면 또 바로 방출이 된다.
즉, 버튼을 아무리 많이 눌러도 설정한 시간 내에 발생한 가장 첫번째 이벤트만 방출이 되는것을 볼 수 있다.
이러한 특징 때문에 throttle은 스크롤을 내릴 때 API요청을 하거나, 버튼을 계속 누르는 것을 방지할때 사용된다.
스크롤을 엄청난 속도로 계속 내리더라도 처음에만 API요청을 하고, 이후에는 설정한 시간동안 대기하기 때문에 역시 불필요한 API 요청을 줄일 수 있을것이다.
'iOS > UIKit' 카테고리의 다른 글
[iOS/UIKit] Realm을 DiffableDataSource와 함께 사용할때 발생할 수 있는 오류 (0) | 2025.03.03 |
---|---|
[iOS/UIKit] Diffable DataSource를 이용해 서로 다른 Cell로 구성하기 - Xcode16에서 발생할 수 있는 오류 (0) | 2025.02.28 |
[iOS/UIKit] RxSwift에서의 Cell의 중첩 구독 문제 (0) | 2025.02.23 |
[iOS/UIKit] RxSwift 용어정리 (0) | 2025.02.20 |
[iOS/UIKit] View Hierarchy 디버깅 팁 (1) | 2025.02.02 |