在 Swift 中节流而不进行反应

Posted

技术标签:

【中文标题】在 Swift 中节流而不进行反应【英文标题】:Throttling in Swift without going reactive 【发布时间】:2017-04-10 12:04:15 【问题描述】:

有没有一种简单的方法可以在响应式编程中实现 Throttle 功能,而无需使用 RxSwift 或类似框架。

我有一个 textField 委托方法,我不想在每次插入/删除字符时触发它。

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

【问题讨论】:

代理每次都会触发。在您的委托方法中,您可以启动一个计时器。如果委托在计时器关闭之前再次触发,请重新启动计时器。当计时器响起时,做任何你需要做的事情。 【参考方案1】:

是的,有可能实现。

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

在软件、节流过程或节流控制器中 有时称为,是负责调节速率的过程 执行哪个应用程序处理,无论是静态的还是 动态的。

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
    


【讨论】:

timer?.invalidate() 简单一点。 我认为现在就可以了。仅使用计时器的问题是:每个新计时器都会执行选择器而不取消之前的调用。这将打败整个观点。并且无法保证对选择器的调用按照假定的顺序进行。 @Carpsen90 您实际上并不需要它们按特定顺序排列。您只需要忽略所有先前的结果。这应该如何完成取决于您的 API。我通常会在请求中传递一些上下文以及上下文中的文本。请求完成后,我可以比较当前文本是否与我们请求的文本相同。 换句话说,选择器应该是可取消的。我去看看。 这不是去抖功能吗?油门功能,不会总是从最后一个 textField 输入触发0.5。相反,无论用户是否输入了新字符,它总是会在0.5 触发。【参考方案2】: 免责声明:我是一名作家。

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 默认没有。

您可以,但您可能需要自己进行复杂的实现。

【讨论】:

以上是关于在 Swift 中节流而不进行反应的主要内容,如果未能解决你的问题,请参考以下文章

使用 Powershell 解析从 Web 请求返回的 JSON 字节流而不写入文件

将 PDF 下载为字节流

Java字节流之ByteArrayInputStream

javaScript基本功之函数防抖与节流

使用 lodash 的节流不使用 ReactJS 进行节流

使用铬和硒进行网络节流