在 Swift 中节流而不反应

Throttling in Swift without going reactive

有没有一种无需使用 RxSwift 或类似框架即可在 Reactive 编程中实现 Throttle 功能的简单方法。

我有一个 textField 委托方法,我不想在每次字符为 inserted/deleted 时触发。

如何使用 vanilla Foundation 做到这一点?

是的,可以实现。

但首先让我们回答一个小问题什么是节流?

In software, a throttling process, or a throttling controller as it is sometimes called, is a process responsible for regulating the rate at which application processing is conducted, either statically or dynamically.

Swift 中的 Throttling 函数示例。

如果您使用委托方法进行描述,您将遇到每次都会调用委托方法的问题。所以我会写一个简短的例子,在你描述的情况下是不可能做到的。

class ViewController: UIViewController {
    
    var timer: Timer?
    
    @IBOutlet weak var textField: UITextField!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        textField.delegate = self
    }
    
    @objc func validate() {
        print("Validate is called")
    }
}

extension ViewController: UITextFieldDelegate {
    
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        
        timer?.invalidate()
        
        timer = Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(self.validate), userInfo: nil, repeats: false);
        
        return true
    }

}
  • 免责声明:我是一名作家。

Throttler 可以成为让您开心的正确武士刀。

您可以在不使用 Throttler 进行反应式编程的情况下进行去抖动和节流,

import Throttler

// advanced debounce, running a first task immediately before initiating debounce.

for i in 1...1000 {
    Throttler.debounce {
        print("debounce! > \(i)")
    }
}

// debounce! > 1
// debounce! > 1000


// equivalent to debounce of Combine, RxSwift.

for i in 1...1000 {
    Throttler.debounce(shouldRunImmediately: false) {
        print("debounce! > \(i)")
    }
}

// debounce! > 1000

Throttler 也可以进行高级去抖动,运行 紧接在启动去抖动之前的第一个事件,Combine 和 RxSwift 默认情况下没有。

你可以,但你自己可能需要一个复杂的实现。