-
-
Save codeactual/3a64468bf4b7e081497385ac3b2f7d77 to your computer and use it in GitHub Desktop.
Synchronously (well) wait for async Task value update
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
| /// Wait for async operation to return value and call callback with the value | |
| /// This class is intended to workaround/simplify async/await + actors isolation | |
| /// https://twitter.com/krzyzanowskim/status/1523233140914876416 | |
| private class AsyncWaiter<T> { | |
| var didReceiveValue: Bool = false | |
| let value: (T) -> Void | |
| let operation: () async throws -> T | |
| init(_ value: @escaping (T) -> Void, operation: @escaping () async throws -> T) { | |
| self.value = value | |
| self.operation = operation | |
| } | |
| func wait() { | |
| Task.detached { | |
| do { | |
| self.value(try await self.operation()) | |
| self.signal() | |
| } catch { | |
| self.signal() | |
| throw error | |
| } | |
| } | |
| while !didReceiveValue { | |
| RunLoop.current.run(mode: .default, before: .distantFuture) | |
| } | |
| } | |
| func signal() { | |
| didReceiveValue = true | |
| } | |
| } | |
| extension Task where Success == Void, Failure == CancellationError { | |
| struct ValueError: LocalizedError { | |
| var errorDescription: String? { | |
| "Didn't receive asynchronous value." | |
| } | |
| } | |
| public static func wait<T>(operation: @escaping () async throws -> T) throws -> T { | |
| var v: T? = nil | |
| AsyncWaiter({ | |
| v = $0 | |
| }, operation: operation).wait() | |
| if let v = v { | |
| return v | |
| } else { | |
| throw ValueError() | |
| } | |
| } | |
| } |
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
| let result: [String] = try Task.wait { | |
| try await foo.getValues() | |
| } | |
| print(result) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment