swift 防抖与节流

作者: 稀释1 | 来源:发表于2021-10-14 09:58 被阅读0次

防抖



import UIKit

class Debouncer {
    
    private let label: String
    private let interval: Int
    private let queue: DispatchQueue
    private var workItem: DispatchWorkItem?
    private var lock: DispatchSemaphoreWrapper
    
    /// interval: 单位毫秒
    init(label: String = "PZDebouncer", interval: Int = 500) {
        self.label = label
        self.interval = interval
        self.queue = DispatchQueue(label: label)
        self.lock = DispatchSemaphoreWrapper(value: 1)
    }
    
    func call(_ callback: @escaping (() -> ())) {
        self.lock.sync {
            self.workItem?.cancel()
            self.workItem = DispatchWorkItem {
                callback()
            }
            
            if let workItem = self.workItem {
                self.queue.asyncAfter(deadline: .now() + DispatchTimeInterval.milliseconds(interval), execute: workItem)
            }
        }
    }
    
}

struct DispatchSemaphoreWrapper {
    private var lock: DispatchSemaphore
    init(value: Int) {
        self.lock = DispatchSemaphore(value: 1)
    }
    
    func sync(execute: () -> ()) {
        _ = lock.wait(timeout: DispatchTime.distantFuture)
        lock.signal()
        execute()
    }
}

节流

//
//  Throttle.swift


import UIKit

class Throttle {

    private let label: String
    private let interval: Int
    private let queue: DispatchQueue
    private var workItem: DispatchWorkItem?
    private var lock: DispatchSemaphoreWrapper
    private var lastTime: Date = Date()
    
    /// interval: 单位毫秒
    init(label: String = "Debouncer", interval: Int = 500) {
        self.label = label
        self.interval = interval
        self.queue = DispatchQueue(label: label)
        self.lock = DispatchSemaphoreWrapper(value: 1)
    }
    
    func call(_ callback: @escaping (() -> ())) {
        self.lock.sync {
            self.workItem?.cancel()
            self.workItem = DispatchWorkItem { [weak self] in
                self?.lastTime = Date()
                callback()
            }
            if let workItem = self.workItem {
                let new = Date()
                let delay = new.timeIntervalSince1970 - lastTime.timeIntervalSince1970 > Double(self.interval)/1000 ? DispatchTimeInterval.milliseconds(0) : DispatchTimeInterval.milliseconds(self.interval)
                self.queue.asyncAfter(deadline: .now() + delay, execute: workItem)
                
            }
        }
    }
    
}

使用

//
//  ViewController.swift
//  防抖和节流


import UIKit

class ViewController: UIViewController {

    let throttle = Throttle(label: "123", interval: 2000)
    let debouncer = Debouncer(label: "123", interval: 2000)
    
    override func viewDidLoad() {
        super.viewDidLoad()
//        testThrottle()
        testDebouncer()
    }
    
    func testThrottle() {
        for _ in 0..<10 {
            sleep(1)
            throttle.call {
                let date = Date()
                print("XQ:\(date.timeIntervalSince1970)")
            }
        }
    }

    func testDebouncer() {
        for i in 0..<100 {
            let delay = i % 2 == 0 ? 1 : 3
            sleep(UInt32(delay))
            debouncer.call {
                let date = Date()
                print("XQ:\(date.timeIntervalSince1970)")
            }
        }
    }

}

相关文章

网友评论

    本文标题:swift 防抖与节流

    本文链接:https://www.haomeiwen.com/subject/qpvyoltx.html