Tunko Development Diary

ReSwift) Filtering Operators(debounce, throttle) 본문

Development/RxSwift

ReSwift) Filtering Operators(debounce, throttle)

Tunko 2022. 6. 1. 16:57

debounce

let disposeBag = DisposeBag()

let tapObservable = Observable<String>.create { observer in
   DispatchQueue.global().async {
      for i in 1...10 {
         observer.onNext("Tap \\(i)")
         Thread.sleep(forTimeInterval: 0.3)
      }
      
      Thread.sleep(forTimeInterval: 1)
      
      for i in 11...20 {
         observer.onNext("Tap \\(i)")
         Thread.sleep(forTimeInterval: 0.5)
      }
      
      observer.onCompleted()
   }
   
   return Disposables.create {
      
   }
}

tapObservable
    .debounce(.milliseconds(1000), scheduler: MainScheduler.instance)
    .subscribe { print($0) }
    .disposed(by: disposeBag)

출력

next(Tap 10)
next(Tap 20)
completed

debounce 첫번째 파라미터 dueTime은 옵저버가 next 이벤트 방출하고 dueTime동안 next이벤트를 방출하지 않는다면, 해당 시점에 마지막으로 방출한 Next 이벤트를 방출합니다.

반대로 지정된 시간 이내에 또다른 next 이벤트가 방출되었다면 타이머를 초기화 합니다.

그후 다시 dueTime동안 대기 후 이시간동안 이벤트가 방출되지 않으면 마지막으로 방출한 Next이벤트를 방출합니다.

이벤트가 방출되면 타이머를 다시 초기화 합니다.

위 예제에서 dueTime에 1초를 넣었습니다. 즉, 0.3초마다 1~10까지 출력하는 중간에 duetime이 지나가기도 전에 다시 이벤트가 들어왔으니 내부타이머가 0.3초마다 초기화 된것을 알 수 있습니다.

Thread.sleep(forTimeInterval: 1) 를 통해 1초를 멈추니 next(Tap 10) 가 출력되었습니다.

그리고 0.5초마다 11~20까지 출력 되는동안 위 과정이 반복됩니다. 따라서next(Tap 20) 이 출력됩니다.

아래의 코드를 추가 했습니다.

buttonTap
    .debounce(.milliseconds(400), scheduler: MainScheduler.instance)
    .subscribe { print($0) }
    .disposed(by: disposeBag)

이번엔 0.4초를 넣었습니다.

next(Tap 10)
next(Tap 11)
next(Tap 12)
next(Tap 13)
next(Tap 14)
next(Tap 15)
next(Tap 16)
next(Tap 17)
next(Tap 18)
next(Tap 19)
next(Tap 20)
completed

출력결과를 보면 0.3초마다 이벤트가 무시되면서 10만들어왔습니다. 후에 0.5초마다 들어온 이벤트는 전부 호출됩니다.

요약

next이벤트 마다 지정한 dueTime 시간만큼의 내부 타이머가 초기화 됩니다. dueTime이 10초라고 가정하면 5초에 들어온 next 이벤트는 10초가 지나야 출력됩니다.

throttle

위에 코드를 재사용 합니다.

tapObservable
    .throttle(.seconds(1), latest: true, scheduler: MainScheduler.instance)
    .subscribe { print($0) }
    .disposed(by: disposeBag)

throttle은 next 이벤트를 지정된 주기마다 1개씩 방출합니다. 짧은시간동안 반복되는 Tap이나 Delegate 이벤트등은 보통 throttle연산지를 사용합니다.

latest 가 true 일때와 false일때 차이점이 있습니다.

latest : true

latest : true일땐 주기를 정확히 지킴

next(Tap 1)
next(Tap 3)
next(Tap 5)
next(Tap 7)
next(Tap 9)
next(Tap 10)
next(Tap 12)
next(Tap 13)
next(Tap 14)
next(Tap 15)
next(Tap 16)
next(Tap 17)
next(Tap 18)
next(Tap 19)
next(Tap 20)
completed

latest : false

latest : false일땐 지정된 주기를 초과할 수 있습니다.

next(Tap 1)
next(Tap 3)
next(Tap 5)
next(Tap 7)
next(Tap 9)
next(Tap 11)
next(Tap 12)
next(Tap 13)
next(Tap 14)
next(Tap 15)
next(Tap 16)
next(Tap 17)
next(Tap 18)
next(Tap 19)
next(Tap 20)
completed
반응형
Comments