Skip to content

Instantly share code, notes, and snippets.

@laevandus
Last active October 15, 2023 00:48
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save laevandus/eb4abc16f0201846b561d3060fb374c3 to your computer and use it in GitHub Desktop.
Save laevandus/eb4abc16f0201846b561d3060fb374c3 to your computer and use it in GitHub Desktop.
extension Publisher {
public func tryAwaitMap<T>(_ transform: @escaping (Self.Output) async throws -> T) -> Publishers.FlatMap<Future<T, Error>, Self> {
flatMap { value in
Future { promise in
Task {
do {
let result = try await transform(value)
promise(.success(result))
}
catch {
promise(.failure(error))
}
}
}
}
}
public func tryAwaitMap<T>(_ transform: @escaping (Self.Output) async throws -> T) -> Publishers.FlatMap<Future<T, Error>, Publishers.SetFailureType<Self, Error>> {
// The same implementation but the returned publisher transforms failures with SetFailureType.
}
}
// Case 1: throwing downstream publisher
$imageURL
.tryMap({ try Self.validateURL($0) })
.tryAwaitMap({ try await ImageProcessor.process($0) })
.map({ Image(uiImage: $0) })
.sink(receiveCompletion: { print("completion: \($0)") },
receiveValue: { print($0) })
.store(in: &cancellables)
// Case 2: non-throwing downstream publisher
$imageURL
.compactMap({ $0 })
.tryAwaitMap({ try await ImageProcessor.process($0) })
.map({ Image(uiImage: $0) })
.sink(receiveCompletion: { print("completion: \($0)") },
receiveValue: { print($0) })
.store(in: &cancellables)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment