RxSwift 中的 throttle 与 debounce 封装记录
项目中需要
连续点击按钮只让第一次生效,用 throttle 操作符即可;
搜索时文本不断变化导致调用多次接口,用 debounce 操作符即可;
实现之后发现每次都要写同样的三四行代码,很啰嗦不说,也不利于统一配置,顺手简易封装,记录一下。
throttle 与 debounce区别总结如下:
Throttle(节气门):每个指定时间段内最多调用一次原始函数。
Debounce(防抖): 原始函数被调用 调用者在指定时间段后停止调用修饰的函数.
🌰🌰: //浅封装: button.rx.safeDrive { (sender) in DDLog(sender.currentTitle as Any) }.disposed(by: dispose) searchBar.rx.safeDrive { (query) in DDLog(query) }.disposed(by: dispose) //极简封装: button.rxDrive { (sender) in DDLog(sender.currentTitle as Any) }.disposed(by: dispose) searchBar.rxDrive { (query) in DDLog(query) }.disposed(by: dispose)
源码
// // RXCocoaHelper.swift // SwiftTemplet // // Created by Bin Shang on 2020/12/24. // Copyright © 2020 BN. All rights reserved. // import UIKit import RxSwift import RxCocoa public extension Reactive where Base: UIButton { var safeTap: ControlEvent<Void> { return ControlEvent.init(events: tap.throttle(.milliseconds(1500), latest: false, scheduler: MainScheduler.instance)) } ///避免连续点击(1.5 秒响应一次) func safeDrive(onNext: @escaping ((Base) -> Void)) -> Disposable { return self.safeTap .asControlEvent() .asDriver() .drive { onNext(self.base) } onCompleted: { } onDisposed: { } } } public extension Reactive where Base: UITextField { ///避免连续调用(1.5 秒响应一次) func safeDrive(_ dueTime: RxSwift.RxTimeInterval = .milliseconds(1500), onNext: @escaping ((String) -> Void)) -> Disposable { return text.orEmpty .asDriver() .distinctUntilChanged() .debounce(dueTime) .drive(onNext: { (query) in onNext(query) }) { } onDisposed: { } } } public extension Reactive where Base: UISearchBar{ ///避免连续调用(1.5 秒响应一次) func safeDrive(_ dueTime: RxSwift.RxTimeInterval = .milliseconds(1500), onNext: @escaping ((String) -> Void)) -> Disposable { return text.orEmpty .asDriver() .distinctUntilChanged() .debounce(dueTime) .drive(onNext: { (query) in onNext(query) }) { } onDisposed: { } } } public extension UIButton{ ///避免连续调用(1.5 秒响应一次) func rxDrive(onNext: @escaping ((UIButton) -> Void)) -> Disposable { return self.rx.safeDrive(onNext: onNext) } } public extension UITextField{ ///避免连续调用(1.5 秒响应一次) func rxDrive(onNext: @escaping ((String) -> Void)) -> Disposable { return self.rx.safeDrive(onNext: onNext) } } public extension UISearchBar{ ///避免连续调用(1.5 秒响应一次) func rxDrive(onNext: @escaping ((String) -> Void)) -> Disposable { return self.rx.safeDrive(onNext: onNext) } }
赞 (0)