Last active
November 24, 2018 22:47
-
-
Save kean/24a3d0c2538647b33006b344ebc283a7 to your computer and use it in GitHub Desktop.
Fake (blocking) Async/Await for https://github.com/kean/FutureX
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
class AsyncAwaitTests: XCTestCase { | |
func testAsyncAwait() { | |
XCTAssertEqual(fakeAsyncAwait().wait().value, 3) | |
} | |
} | |
func fakeAsyncAwait() -> Future<Int, Error> { | |
return Future.async { | |
// Add delay to demonstrate that `await` for `Future<_, Never>` don't | |
// require `try`. | |
Future.after(seconds: 1).await() | |
// Performing async tasks in a synchronous manner. | |
let data = try loadData().await() | |
let string = try decodeData(data).await() | |
return string.count | |
} | |
} | |
// WARNING: this won't compile, it's based on the https://gist.github.com/lattner/429b9070918248274f25b714dcfc7619 | |
func realAsyncAwait() async throws -> Int { | |
// This is a contribed example. | |
await Future.after(seconds: 1) | |
let string = try await decodeData(loadData()) | |
return string.count | |
} | |
func loadData() -> Future<Data, Error> { | |
let promise = Promise<Data, Error>() | |
let data = "123".data(using: .utf8)! | |
DispatchQueue.global().asyncAfter(deadline: .now() + .seconds(1)) { | |
promise.succeed(value: data) | |
} | |
return promise.future | |
} | |
func decodeData(_ data: Data) -> Future<String, Error> { | |
let promise = Promise<String, Error>() | |
DispatchQueue.global().asyncAfter(deadline: .now() + .seconds(1)) { | |
// Some long async task here | |
let string = String(data: data, encoding: .utf8)! | |
// Using force unwrap just for a demo purposes, production code | |
// must have error handling! | |
promise.succeed(value: string) | |
} | |
return promise.future | |
} |
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
// WARNING: This is just a demo. Real async/await is not blocking | |
// and requires compiler suppport. In this demo async/await is | |
// blocking and goes down to the kernel to block threads. | |
// MARK: - Async/Await | |
extension Future where Error == Swift.Error { | |
public static func async(_ closure: @escaping () throws -> Value) -> Future { | |
let promise = Promise() | |
asyncQueue.async { | |
do { | |
let value = try closure() | |
promise.succeed(value: value) | |
} catch { | |
promise.fail(error: error) | |
} | |
} | |
return promise.future | |
} | |
public func await() throws -> Value { | |
switch wait() { | |
case let .success(value): return value | |
case let .failure(error): throw error | |
} | |
} | |
} | |
extension Future where Error == Never { | |
public func await() -> Value { | |
return wait().value! | |
} | |
} | |
private let asyncQueue = DispatchQueue(label: "com.github.kean.futurex.async-queue", attributes: .concurrent) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment