Last active
December 19, 2019 09:19
-
-
Save jrsonline/dd9799929e1aceb5d99e83fc6ac2b43b to your computer and use it in GitHub Desktop.
Simple implementation of RxSwift's "toBlocking" for Apple's Combine, now using the DispatchQueue
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
extension Publisher { | |
func toBlockingResult(timeout: Int) -> Result<[Self.Output],BlockingError> { | |
var result : Result<[Self.Output],BlockingError>? | |
let semaphore = DispatchSemaphore(value: 0) | |
let sub = self | |
.collect() | |
.mapError { error in BlockingError.otherError(error) } | |
.timeout( | |
.seconds(timeout), | |
scheduler: DispatchQueue.main, | |
customError: { BlockingError.timeoutError(timeout) } | |
).sink( | |
receiveCompletion: { compl in | |
switch compl { | |
case .finished: break | |
case .failure( let f ): result = .failure(f) | |
} | |
semaphore.signal() | |
}, | |
receiveValue: { value in | |
result = .success(value) | |
semaphore.signal() | |
} | |
) | |
// Wait for a result, or time out | |
if semaphore.wait(timeout: .now() + .seconds(timeout)) == .timedOut { | |
sub.cancel() | |
return .failure(BlockingError.timeoutError(timeout)) | |
} else { | |
return result ?? .success([]) | |
} | |
} | |
} | |
enum BlockingError : Error { | |
case timeoutError(Int) | |
case otherError(Error) | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment