-
-
Save astrokin/e2249927b5f4ec6e7ae4da272332733b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://github.com/avito-tech | |
// | |
// Sampler is like a baby of Debouncer and Throttler. | |
// | |
// Unlike Debouncer, sampler executes action immediately (if there are no actions before, for time > delay) | |
// Unlike Throttler it guarantees that last action in sequence will be executed (see last error in example) | |
/// CAUTION: This class isn't thread-safe | |
public final class Sampler { | |
// MARK: - Public properite | |
public let delay: TimeInterval | |
// MARK: - Private properite | |
private let queue: DispatchQueue | |
private var closure: (() -> ())? | |
private var isDelaying = false | |
// MARK: - Init | |
public init(delay: TimeInterval, queue: DispatchQueue = DispatchQueue.main) { | |
avitoAssert(delay >= 0, "Sampler can't have negative delay") | |
self.delay = delay | |
self.queue = queue | |
} | |
// MARK: - Public | |
public func sample(_ closure: @escaping () -> ()) { | |
if isDelaying { | |
self.closure = closure | |
} else { | |
queue.async { | |
closure() | |
} | |
self.closure = nil | |
isDelaying = true | |
queue.asyncAfter(deadline: .now() + delay) { [weak self] in | |
self?.isDelaying = false | |
if let closure = self?.closure { | |
self?.sample(closure) | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment