【发布时间】:2020-10-15 21:47:28
【问题描述】:
下面的组合链中是否有一种方法可以在一个地方处理所有错误?如果我不处理 flatMap 中的错误,$text 发布者将永远不会再次发出。谢谢。
$text
.debounce(for: .seconds(0.5), scheduler: DispatchQueue.main)
.flatMap {
Repository().retrieve(query: $0)
.receive(on: DispatchQueue.main)
.catch { err -> AnyPublisher<[Beer], Never> in
self.serverError = err.displayValue
return Just([]).eraseToAnyPublisher()
}
}
.map { $0.map { ItemViewModel($0) } }
.receive(on: DispatchQueue.main)
.sink {[weak self] val in
self?.items = val
}.store(in: &cancellables)
【问题讨论】:
-
您正在在 flatMap 中捕获它,这就是如何做到的。请参阅此处的“未终止失败”部分apeth.com/UnderstandingCombine/operators/…
-
@matt 我想知道是否有办法在上游发布者中使用
replaceError([])来处理它,但这会结束发布者。如果我有多个flatMap,似乎它会变得相当复杂 -
好吧,如果您阅读了我发送给您的链接,您就会知道答案。如果在主管道中出现错误、捕获或其他错误,它会过滤到发布者并停止发布。我想,您可以编写一个自定义运算符,它拒绝将故障传播到管道上,但是没有这样的本机运算符。除此之外,在平面图中捕捉故障就是你要做的。如果您发现自己在多个 flatMap 中使用相同的运算符序列,则可以将 它们 合并为自定义运算符。
-
顺便说一句,我不知道您认为
self.serverError = err.displayValue的用途是什么,但我认为这是一个非常糟糕的主意。您不应该因为它的副作用而运行 Combine 管道。如果您想产生错误消息,请将其传递到管道并在接收器中进行处理。 -
感谢@matt 的文章,现在真的很有意义。我理解你所说的没有副作用的意思,但我想向用户显示一个错误,但我的谴责发布者仍然处于活动状态。如果我抛出该错误,谴责将完成并且不再发出。