Skip to content

Instantly share code, notes, and snippets.

@frootloops
Created February 8, 2018 20:12
Show Gist options
  • Save frootloops/6f1e7d7d69c7bd7b48d7e3dcd7ba190d to your computer and use it in GitHub Desktop.
Save frootloops/6f1e7d7d69c7bd7b48d7e3dcd7ba190d to your computer and use it in GitHub Desktop.
enum Result<T> {
case failure(Error)
case success(T)
}
let requestQueue = DispatchQueue(label: "RequestQueue", qos: .background)
/// Mock request that waits for 0.5 seconds and then call the completion block
///
/// - Parameter completion: the block of code to execute for the request
func request(completion: @escaping () -> Void) {
requestQueue.asyncAfter(deadline: .now() + 0.5) { completion() }
}
func combine<A, B>(_ operation1: @escaping (@escaping (Result<A>) -> Void) -> Void,
_ operation2: @escaping (@escaping (Result<B>) -> Void) -> Void) -> (@escaping (Result<(A, B)>) -> Void) -> Void {
return { result in
let group = DispatchGroup()
var result1: Result<A> = .failure(NSError(domain: "", code: 0, userInfo: nil))
var result2: Result<B> = .failure(NSError(domain: "", code: 0, userInfo: nil))
group.enter()
operation1 { result in
result1 = result
group.leave()
}
group.enter()
operation2 { result in
result2 = result
group.leave()
}
group.notify(queue: .main) {
switch (result1, result2) {
case let (.failure(error), _), let (_, .failure(error)):
result(.failure(error))
case let (.success(value1), .success(value2)):
result(.success((value1, value2)))
}
}
}
}
func async1(_ block: @escaping (Result<String>) -> Void) {
request {
print("async1")
block(.success("yes"))
}
}
func async2(_ block: @escaping (Result<Int>) -> Void) {
request {
print("async2")
block(.success(1))
}
}
func async3(_ block: @escaping (Result<Int>) -> Void) {
request {
print("async3")
block(.success(1))
}
}
let test = combine(combine(async1, async2), async3)
test { result in }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment