我有一个从不发布条目的发布者,它只完成或失败并出现错误(AnyPublisher<Never, Error>
)。我想将该发布者转换为在第一个发布者完成(AnyPublisher<Value, Error>
)或通过任何错误时发出值的发布者。我想在第一家发行商完成发行后创造这种价值。我可以这样做,但是看起来很乱:
func demo() -> AnyPublisher<Int, Error> {
// Using Empty just for demo purposes
let firstPublisher = Empty<Never, Error>(completeImmediately: true).eraseToAnyPublisher()
var cancellable: AnyCancellable?
return Future<Int, Error> { promise in
cancellable = firstPublisher
.sink { completion in
switch completion {
case .failure(let error):
promise(.failure(error))
case .finished:
// some operation that generates value
let value:Int = 1
promise(.success(value))
}
} receiveValue: { _ in
}
}
.handleEvents(receiveCancel: {
cancellable?.cancel()
})
.eraseToAnyPublisher()
}
还有更好的方法吗?比如:
extension AnyPublisher {
func completionMap<T, P>(_: (_ completion: Subscribers.Completion<Self.Failure>) -> P) -> P where P: Publisher, T == P.Output, Self.Failure == P.Failure {
/// ???
}
}
func demo() -> AnyPublisher<Int, Error> {
// Using Empty just for demo purposes
let firstPublisher = Empty<Never, Error>(completeImmediately: true).eraseToAnyPublisher()
return firstPublisher
.completionMap { completion -> AnyPublisher<Int, Error> in
switch completion {
case .failure(let error):
return Fail(error: error).eraseToAnyPublisher()
case .finished:
// some operation that generates value
let value:Int = 1
return Just(value).setFailureType(to: Error.self).eraseToAnyPublisher()
}
}.eraseToAnyPublisher()
}
您可以使用.append
(它返回Publishers.Concatenate
)作为在第一个发布者完成后发出值的方式。
let firstPublisher: AnyPublisher<Never, Error> = ...
let demo = firstPublisher
.map { _ -> Int in }
.append([1])
如果firstPublisher
成功完成,上面将发出1
,否则将出错。