項目中需要
- 連續(xù)點擊按鈕只讓第一次生效馍佑,用 throttle 操作符即可;
- 搜索時文本不斷變化導(dǎo)致調(diào)用多次接口,用 debounce 操作符即可忍宋;
實現(xiàn)之后發(fā)現(xiàn)每次都要寫同樣的三四行代碼帝火,很啰嗦不說溜徙,也不利于統(tǒng)一配置,順手簡易封裝犀填,記錄一下蠢壹。
throttle 與 debounce區(qū)別總結(jié)如下:
Throttle(節(jié)氣門):每個指定時間段內(nèi)最多調(diào)用一次原始函數(shù)。
Debounce(防抖): 原始函數(shù)被調(diào)用 調(diào)用者在指定時間段后停止調(diào)用修飾的函數(shù).
????:
//淺封裝:
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))
}
///避免連續(xù)點擊(1.5 秒響應(yīng)一次)
func safeDrive(onNext: @escaping ((Base) -> Void)) -> Disposable {
return self.safeTap
.asControlEvent()
.asDriver()
.drive {
onNext(self.base)
} onCompleted: {
} onDisposed: {
}
}
}
public extension Reactive where Base: UITextField {
///避免連續(xù)調(diào)用(1.5 秒響應(yīng)一次)
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{
///避免連續(xù)調(diào)用(1.5 秒響應(yīng)一次)
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{
///避免連續(xù)調(diào)用(1.5 秒響應(yīng)一次)
func rxDrive(onNext: @escaping ((UIButton) -> Void)) -> Disposable {
return self.rx.safeDrive(onNext: onNext)
}
}
public extension UITextField{
///避免連續(xù)調(diào)用(1.5 秒響應(yīng)一次)
func rxDrive(onNext: @escaping ((String) -> Void)) -> Disposable {
return self.rx.safeDrive(onNext: onNext)
}
}
public extension UISearchBar{
///避免連續(xù)調(diào)用(1.5 秒響應(yīng)一次)
func rxDrive(onNext: @escaping ((String) -> Void)) -> Disposable {
return self.rx.safeDrive(onNext: onNext)
}
}