RxSwift의 Debounce와 Throttle

Swift 애호회 Advent Calendar 2017의 12일째 담당 @에서 카토 토로입니다.

어제는 @marty-suzuki"Swift4에서 protocol의 asociatedtype으로 할 수 있게 된 것"이었습니다.
오늘은 "RxSwift의 Debounce와 Throttle"에 관한 것입니다.

RxSwift의 operator에 Debounce와 Throttle이 있지만,
「어라, 어느 쪽이 어떤 동작이었을까?」라고 생각한 적은 없습니까.
잊었을 때이 기사를보십시오

패턴은 세 가지가 있습니다.


  • Debounce
  • Throttle (latest true)
  • Throttle (latest false)

  • 다음의 스트림을 예로 합니다.
    ※ 확인한 version은 RxSwift 4.0.0
    let observable = Observable<Int>.create { observer in
    
        observer.onNext(1)
        observer.onNext(2)
        observer.onNext(3)
    
        sleep(2)
    
        observer.onNext(4)
        observer.onNext(5)
        observer.onNext(6)
    
        sleep(2)
    
        observer.onCompleted()
        return Disposables.create()
        }
    



    Debounce



    지정 기간 새로운 이벤트가 발행되지 않게 되고 나서, 마지막에 발행된 이벤트를 발행합니다. 도중의 이벤트는 무시됩니다.
    _ = observable
        .debounce(1, scheduler: scheduler) // 3, 6
        .subscribe(onNext: {
            print("debounce: \($0)")
        })
    

    그림으로 보겠습니다.


    Throttle



    RxSwift 3.4.0에서 latest 매개 변수가 추가되었습니다.
    default는 true입니다.

    측정이 시작된 첫 번째 이벤트와 지정된 기간 내에 마지막으로 발행된 이벤트(첫 번째 이벤트 이외)를 발행합니다. 도중의 이벤트는 무시합니다.
    latest가 false인 경우, 계측이 개시된 최초의 이벤트를 발행해, 지정 기간내의 이벤트는 모두 무시합니다.

    debounce와의 차이는, 지정 기간의 계측이 개시된 최초의 이벤트를 발행하는 것, latest가 true의 경우는 지정 기간내에서 발행된 이벤트(첫 번째 이벤트 이외)가 지정 기간 경과하면 반드시 발행한다 그건 그렇고.

    Throttle (latest true)


    _ = observable
        .throttle(1, latest: true, scheduler: scheduler) // 1, 3, 4, 6
        .subscribe(onNext: {
            print("throttle true: \($0)")
        })
    

    그림으로 보겠습니다.


    Throttle (latest false)


    _ = observable
        .throttle(1, latest: false, scheduler: scheduler) // 1, 4
        .subscribe(onNext: {
            print("throttle false: \($0)")
        })
    

    그림으로 보겠습니다.


    Example



    실제로 사용하는 예입니다.
    debounce는 증분 검색 등으로 API를 너무 두드리지 않게하는 데 유용하지 않습니까?
    throttle latest false는 버튼 연타 방지 등 다양한 용도가있을 것 같습니다.
    throttle latest true는 별로 사용소가 떠오르지 않으므로, 사용하고 있는 분은 사용예 교수해 주세요
    
    class ViewController: UIViewController {
    
        @IBOutlet private weak var searchBar: UISearchBar!
        @IBOutlet private weak var button: UIButton!
        private let disposeBag = DisposeBag()
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            searchBar.rx.text
                .debounce(0.3, scheduler: MainScheduler.instance)
                .subscribe(onNext: { text in
                    print("UISearchBar debounce: \(text ?? "") \(Date())")
                })
                .disposed(by: disposeBag)
    
            button.rx.tap.asObservable()
                .throttle(1.0, latest: false, scheduler: MainScheduler.instance)
                .subscribe(onNext: { _ in
                    print("UIButton throttle latest false: \(Date())")
                })
                .disposed(by: disposeBag)
        }
    }
    

    이상

    Swift 애호회 Advent Calendar 2017 내일은 @ 미즈코아입니다!

    좋은 웹페이지 즐겨찾기