Поскольку преобразование flatMap
возвращает издателя, вам не нужно строго tryFlatMap
. Вы можете использовать do/catch
внутри закрытия преобразования и возвращать издателя Fail
, если обнаружите ошибку.
import Combine
func someFunction(of i: Int) throws -> AnyPublisher<Int, Error> {
return Just(i + 1)
.setFailureType(to: Error.self)
.eraseToAnyPublisher()
}
let upstream: AnyPublisher<Int, Error> = Just(100)
.setFailureType(to: Error.self)
.eraseToAnyPublisher()
upstream
.flatMap({ i -> AnyPublisher<Int, Error> in
do {
return try someFunction(of: i).eraseToAnyPublisher()
} catch {
return Fail(error: error).eraseToAnyPublisher()
}
})
Вы можете написать свой собственный оператор tryFlatMap
, если хотите:
extension Publisher {
func tryFlatMap<Pub: Publisher>(
_ transform: @escaping (Output) throws -> Pub
) -> Publishers.FlatMap<AnyPublisher<Pub.Output, Error>, Self> {
return flatMap({ input -> AnyPublisher<Pub.Output, Error> in
do {
return try transform(input)
.mapError { $0 as Error }
.eraseToAnyPublisher()
} catch {
return Fail(outputType: Pub.Output.self, failure: error)
.eraseToAnyPublisher()
}
})
}
}
А затем используйте это так:
upstream
.tryFlatMap { try someFunction(of: $0) }