Created
March 30, 2020 15:35
-
-
Save illescasDaniel/b33e6503822d3a9723f7b306cc01e820 to your computer and use it in GitHub Desktop.
Some convenient methods for Dispatch group to synchronize async function calls - very useful for testing
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
| extension DispatchGroup { | |
| typealias Callback<T> = (T) -> Void | |
| typealias ClosureCallback<T> = Callback<Callback<T>> | |
| enum AwaitError: Error { | |
| case timeout | |
| case nilValue | |
| } | |
| /// You should call this method inside a custom queue | |
| func awaitResult<ElementType, ErrorType: Error>(timeout: DispatchWallTime = .now() + .seconds(10), block: @escaping ClosureCallback<Result<ElementType, ErrorType>> ) throws -> Result<ElementType, ErrorType> { | |
| self.enter() | |
| var result: Result<ElementType, ErrorType>! | |
| let resultF: (Result<ElementType, ErrorType>) -> Void = { r in | |
| result = r | |
| self.leave() | |
| } | |
| block(resultF) | |
| if self.wait(wallTimeout: timeout) != .success { | |
| throw AwaitError.timeout | |
| } | |
| if let result = result { | |
| return result | |
| } else { | |
| throw AwaitError.nilValue | |
| } | |
| } | |
| /// You should call this method inside a custom queue | |
| func awaitResultValue<ElementType, ErrorType: Error>(timeout: DispatchWallTime = .now() + .seconds(10), block: @escaping ClosureCallback<Result<ElementType, ErrorType>> ) throws -> ElementType { | |
| return try awaitResult(timeout: timeout, block: block).get() | |
| } | |
| /// You should call this method inside a custom queue | |
| func awaitValue<ElementType>(timeout: DispatchWallTime = .now() + .seconds(10), block: @escaping ClosureCallback<ElementType> ) throws -> ElementType { | |
| self.enter() | |
| var result: ElementType! | |
| let resultF: (ElementType) -> Void = { r in | |
| result = r | |
| self.leave() | |
| } | |
| block(resultF) | |
| if self.wait(wallTimeout: timeout) != .success { | |
| throw AwaitError.timeout | |
| } | |
| if let result = result { | |
| return result | |
| } else { | |
| throw AwaitError.nilValue | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment