Skip to content

Instantly share code, notes, and snippets.

@wilg
Last active April 17, 2020 02:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wilg/6f2fa0412b5a1beec6748077fea159d1 to your computer and use it in GitHub Desktop.
Save wilg/6f2fa0412b5a1beec6748077fea159d1 to your computer and use it in GitHub Desktop.
A helper function to make error propagation for asynchronous operations easier in Swift.
/// `asyncMap` helps you with error propagation for asynchronous tasks.
/// - Parameters:
/// - onFailure: A closure that will be called in an error condition if in an error state.
/// - onSuccess: A closure that will be called with your success value if succesful.
/// - Returns: A closure that will call `onError` if it is passed a failing result, and that will execute `onSuccess` if it is successful.
func asyncMap<Success, NeverSuccess, Error: Swift.Error>(
_ onFailure: @escaping ((Result<NeverSuccess, Error>) -> Void),
_ onSuccess: @escaping (Success) -> Void
) -> ((Result<Success, Error>) -> Void) {
return { result in
switch result {
case let .success(s):
onSuccess(s)
case let .failure(e):
onFailure(.failure(e))
}
}
}
func complexAsyncOperation(done: @escaping (Result<Void, Error>) -> Void) {
complexThing1(asyncMap(done) { str in
print("got string: \(str)")
complexThing2(asyncMap(done) { num in
print("got numbers: \(num)")
done(.success(()))
})
})
}
///
func complexThing1(_ done: @escaping (Result<String, Error>) -> Void) {
// trivial example of async task returning String
DispatchQueue.main.async {
done(.success("abc"))
}
}
func complexThing2(_ done: @escaping (Result<Int, Error>) -> Void) {
// trivial example of async task returning Int
DispatchQueue.main.async {
done(.success(123))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment