Created
September 17, 2018 10:15
-
-
Save miguelfermin/1628c7e227498f09c85aff668d47eb6d to your computer and use it in GitHub Desktop.
Simple Swift implementation of the Future design pattern.
This file contains hidden or 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
enum Result<T> { | |
case value(T) | |
case error(Error) | |
} | |
final class Future<T> { | |
private let queue: DispatchQueue | |
private var callbacks: [(Result<T>) -> ()] = [] | |
private var result: Result<T>? | |
init(compute: (@escaping (Result<T>) -> Void) -> Void) { | |
let label = "com.mafsoftware.Future.\(UUID().uuidString)" | |
queue = DispatchQueue(label: label, attributes: .concurrent) | |
queue.sync { | |
compute(self.send) | |
} | |
} | |
private func send(_ value: Result<T>) { | |
queue.sync { | |
assert(result == nil) | |
result = value | |
for callback in callbacks { | |
callback(value) | |
} | |
callbacks = [] | |
} | |
} | |
final func completionHandler(callback: @escaping (Result<T>) -> ()) { | |
queue.sync { | |
if let value = result { | |
DispatchQueue.main.async { callback(value) } | |
} else { | |
callbacks.append(callback) | |
} | |
} | |
} | |
} | |
// How to consume: | |
struct Car { let make: String, model: String } | |
// a func that returns a Future "Car" | |
func fetchCat() -> Future<Car> { | |
let future = Future<Car> { result in | |
Time.sleep(for: 1) {result(.value(Car(make: "Honda", model: "Civic")))} | |
} | |
return future | |
} | |
let carFuture = fetchCat() | |
carFuture.completionHandler { result in | |
switch result { | |
case .value(let value): print("value0: \(value)") | |
case .error(let error): print("error: \(error)") | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment