我在我的Rx代码中遵循一个模式,我通常有一个Observable触发器,我用flatMap为网络请求创建另一个Observable。简化示例:
enum ViewModelError: Error {
case bang
}
enum DataTaskError: Error {
case bang
}
func viewModel(trigger: Observable<Void>,
dataTask: Observable<Result<SomeType, DataTaskError>>) -> Observable<Result<AnotherType, ViewModelError>> {
let apiResponse = trigger
.flatMap { dataTask }
}
我遇到了一些麻烦。我可以将Result用作Output类型,而将Never用作Failure类型,但这感觉是对API的滥用。
func viewModel(trigger: AnyPublisher<Void, Never>,
dataTask: AnyPublisher<SomeType, DataTaskError>) -> AnyPublisher<AnotherType, ViewModelError> {
let apiResponse = trigger
.flatMap { dataTask }
}
我收到编译错误:
Instance method 'flatMap(maxPublishers:_:)' requires the types 'Never' and 'DataTaskError' be equivalent
我可以使用mapError并将两个错误都转换为Error,但是我需要一个DataTaskError才能创建我的ViewModelError。
感觉不应该那么困难,并且看起来很普通。我可能只是误解了一些基本知识,朝正确方向的观点将不胜感激。
答案 0 :(得分:2)
如果您的发布者的失败类型为“从不”,则可以使用setFailureType(to:)
来匹配其他发布者的失败类型。请注意,根据文档,仅当故障类型为“从不”时,才可以使用此方法。当您遇到实际故障类型时,可以使用mapError(_:)
转换错误。因此,您可以执行以下操作:
func viewModel(trigger: AnyPublisher<Void, Never>,
dataTask: AnyPublisher<SomeType, DataTaskError>) -> AnyPublisher<AnotherType, ViewModelError> {
trigger
.setFailureType(to: ViewModelError.self) // Publisher<Void, ViewModelError>
.flatMap {
dataTask // Publisher<SomeType, DataTaskError>
.mapError { _ in ViewModelError.bang } // Publisher<SomeType, ViewModelError>
.map { _ in AnotherType() } // Publisher<AnotherType, ViewModelError>
}
.eraseToAnyPublisher()
}