Last active
February 28, 2017 19:28
-
-
Save iThinker/7d44478496422e96a661cdce2a1ec4b2 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
import Foundation | |
import PlaygroundSupport | |
PlaygroundPage.current.needsIndefiniteExecution = true | |
func async<T>(_ executable: @escaping @autoclosure () -> T, _ priority: DispatchQoS.QoSClass = DispatchQoS.QoSClass.default, completion: @escaping (T) -> Void) { | |
DispatchQueue.global(qos: priority).async { | |
let result = executable() | |
DispatchQueue.main.async { | |
completion(result) | |
} | |
} | |
} | |
func asyncWithError<T>(_ executable: @escaping @autoclosure () throws -> T, _ priority: DispatchQoS.QoSClass = DispatchQoS.QoSClass.default, completion: @escaping (T?, Error?) -> Void) { | |
DispatchQueue.global(qos: priority).async { | |
var result: T? = nil | |
var error: Error? = nil | |
do { | |
result = try executable() | |
} | |
catch let caughtError { | |
error = caughtError | |
} | |
DispatchQueue.main.async { | |
completion(result, error) | |
} | |
} | |
} | |
infix operator => | |
func =><T>(left: @escaping @autoclosure () -> T, right: @escaping (T) -> Void) { | |
async(left, completion: right) | |
} | |
infix operator =>> | |
func =>><T>(left: @escaping @autoclosure () throws -> T, right: @escaping (T?, Error?) -> Void) { | |
asyncWithError(left, completion: right) | |
} | |
func toAsync<U, T>(_ executable: @escaping (U) -> T) -> ((U, @escaping ((T) -> Void)) -> Void) { | |
return { | |
input, completion in | |
async(executable(input), completion: completion) | |
} | |
} | |
func toAsyncWithError<U, T>(_ executable: @escaping (U) throws -> T) -> ((U, @escaping ((T?, Error?) -> Void)) -> Void) { | |
return { | |
input, completion in | |
do { | |
asyncWithError(try executable(input), completion: completion) | |
} | |
catch {} | |
} | |
} | |
class TestExecutor { | |
func perform(_ input: String) -> String { | |
return input + " Performed" | |
} | |
enum Error: String, Swift.Error, LocalizedError { | |
case Empty | |
var errorDescription: String? { | |
return self.rawValue | |
} | |
} | |
func throwingPerform(_ input: String) throws -> String { | |
if input.isEmpty { | |
throw Error.Empty | |
} | |
return self.perform(input) | |
} | |
func multiplePerform(_ input: String, secondArg: Int) -> String { | |
return input + " " + String(secondArg) + " Multiple Args Performed" | |
} | |
func multipleThrowingPerform(_ input: String, secondArg: Int) throws -> String { | |
if input.isEmpty || secondArg == 0 { | |
throw Error.Empty | |
} | |
return self.multiplePerform(input, secondArg: secondArg) | |
} | |
} | |
let executor = TestExecutor() | |
let syncResult = executor.perform("Hi") | |
let group = DispatchGroup() | |
group.enter() | |
executor.perform("Operator") => { result in | |
print(result) | |
group.leave() | |
} | |
group.enter() | |
executor.perform("Wut") =>> { result, error in | |
print("result: ", result ?? "no result", ", error: ", error?.localizedDescription ?? "no error") | |
group.leave() | |
} | |
group.enter() | |
try executor.throwingPerform("") =>> { result, error in | |
print("result: ", result ?? "no result", ", error: ", error?.localizedDescription ?? "no error") | |
group.leave() | |
} | |
group.enter() | |
async(executor.perform("Async")) { result in | |
print(result) | |
group.leave() | |
} | |
group.enter() | |
asyncWithError(try executor.throwingPerform("")) { result, error in | |
print("result: ", result ?? "no result", ", error: ", error?.localizedDescription ?? "no error") | |
group.leave() | |
} | |
func finishAsync<T>(_ result: T) { | |
print(result) | |
group.leave() | |
} | |
group.enter() | |
executor.perform("Finish Function") => finishAsync | |
let asyncPerform = toAsync(executor.multiplePerform) | |
group.enter() | |
asyncPerform(("Asynced Function", 5)) { result in | |
print(result) | |
group.leave() | |
} | |
let asyncPerformWithError = toAsyncWithError(executor.multipleThrowingPerform) | |
group.enter() | |
asyncPerformWithError(("", 0)) { result, error in | |
print("result: ", result ?? "no result", ", error: ", error?.localizedDescription ?? "no error") | |
group.leave() | |
} | |
group.notify(queue: .main) { | |
PlaygroundPage.current.finishExecution() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment