Skip to content

Instantly share code, notes, and snippets.

@astrokin
Forked from maxsokolov/Mobius2017.Sampler.swift
Created February 10, 2018 08:53
Show Gist options
  • Save astrokin/e2249927b5f4ec6e7ae4da272332733b to your computer and use it in GitHub Desktop.
Save astrokin/e2249927b5f4ec6e7ae4da272332733b to your computer and use it in GitHub Desktop.
// 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