我有一个从不发出项目并且仅完成或失败并出现错误 ( 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()
}
Run Code Online (Sandbox Code Playgroud)
这可以用更好的方法来完成吗?就像是:
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()
}
Run Code Online (Sandbox Code Playgroud)
您可以使用.append(返回 a Publishers.Concatenate)作为在第一个发布者完成后发出值的方式。
let firstPublisher: AnyPublisher<Never, Error> = ...
let demo = firstPublisher
.map { _ -> Int in }
.append([1])
Run Code Online (Sandbox Code Playgroud)
1如果成功完成,上面的内容将会发出firstPublisher,否则会出错。
| 归档时间: |
|
| 查看次数: |
1382 次 |
| 最近记录: |