Я думаю, вы ошибаетесь, что PassthroughSubject
может опубликовать sh дополнительных выходных данных после публикации ошибки. Оно не может. После того, как вы наберете p.send(completion: ...)
, все вызовы на p.send(...)
будут игнорироваться. Кроме того, если вы подпишетесь на p
после того, как позвоните p.send(completion: ...)
, p
немедленно завершит новую подписку и не отправит никаких выходных данных.
Таким образом, вы не можете отправить свою ошибку как .failure
, если вы хотите отправить больше значений после. Вместо этого измените тип Output
вашего издателя на Result<Int, NumberError>
, а его тип Failure
на Never
:
import Combine
enum NumberError: Int, Error {
case isFatal, canContinue
}
struct Numbers {
let p = PassthroughSubject<Result<Int, NumberError>, Never>()
func start(max: Int) {
let bad = (max + 1) / 2
for i in (1...max) {
if bad == i {
p.send(.failure(NumberError.canContinue))
} else {
p.send(.success(i))
}
}
p.send(completion: .finished)
}
}
Но теперь вы не можете использовать catch
для обработки ошибки, потому что это не считаться неудачей. Вместо этого вы можете использовать map
:
let n = Numbers()
let c = n.p
.map({
switch $0 {
case .success(let i): return i
case .failure(_): return -1
}
})
.sink(receiveCompletion: {result in
switch result {
case .failure:
print("Error")
case .finished:
print("Finished")
}
}, receiveValue: {
print($0)
})
n.start(max: 5)
Вывод:
1
2
-1
4
5
Finished