【发布时间】:2019-02-24 19:20:39
【问题描述】:
我有一个由多个运算符组成的序列。在这个序列处理过程中,总共有 7 个地方会产生错误。我遇到了一个序列不符合我预期的问题,我正在寻找一个优雅的解决方案:
let inputRelay = PublishRelay<Int>()
let outputRelay = PublishRelay<Result<Int>>()
inputRelay
.map{ /*may throw multiple errors*/}
.flatmap{ /*may throw error*/ }
.map{}
.filter{}
.map{ _ -> Result<Int> in ...}
.catchError{}
.bind(to: outputRelay)
我认为catchError 会简单地捕获错误,允许我将其转换为失败结果,但防止序列被释放。但是,我看到第一次发现错误时,整个序列都被释放,不再有事件通过。
如果没有这种行为,我会留下一个令人毛骨悚然的结果,并且必须多次分支我的序列以将Result.failure(Error) 定向到输出。存在不可恢复的错误,所以retry(n) 不是一个选项:
let firstOp = inputRelay
.map{ /*may throw multiple errors*/}
.share()
//--Handle first error results--
firstOp
.filter{/*errorResults only*/}
.bind(to: outputRelay)
let secondOp = firstOp
.flatmap{ /*may throw error*/ }
.share()
//--Handle second error results--
secondOp
.filter{/*errorResults only*/}
.bind(to: outputRelay)
secondOp
.map{}
.filter{}
.map{ _ -> Result<Int> in ...}
.catchError{}
.bind(to: outputRelay)
^ 这很糟糕,因为大约有 7 个地方可能会引发错误,而且我不能每次都继续分支序列。
RxSwift 运算符如何捕获所有错误并在最后发出失败结果,但不处理第一个错误时的整个序列?
【问题讨论】:
-
恐怕这是 Rx 的方式,它不是关于资源被释放的问题,如果观察者发出错误,它被标记为已完成,正如 Rx 所说,一个 observable 不能在之后发出值发生错误。所以你这里只有一种方法,如果可以,不要发出错误,你可以将游览值和错误包装到一个将一直发出的对象中,订阅者必须检查是否有错误。您也可以尝试使用重试,它使您可以选择返回一个观察者,如果发生错误(不仅在 n 次之后)将执行该观察者
-
如果在 UI 中使用它,您不能使用驱动程序并在它捕获该运算符的任何错误时返回一些东西吗?
.asDriver(onErrorJustReturn: nil)因为驱动程序永远不会出错。
标签: ios error-handling observable rx-swift onerror