mik*_*ike 5 frp ios swift combine
我在我的 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 }
}
Run Code Online (Sandbox Code Playgroud)
我遇到了一些麻烦的Combine等价物。我可以使用 Result 作为输出类型,使用 Never 作为失败类型,但这感觉像是对 API 的滥用。
func viewModel(trigger: AnyPublisher<Void, Never>,
dataTask: AnyPublisher<SomeType, DataTaskError>) -> AnyPublisher<AnotherType, ViewModelError> {
let apiResponse = trigger
.flatMap { dataTask }
}
Run Code Online (Sandbox Code Playgroud)
我收到编译错误:
Instance method 'flatMap(maxPublishers:_:)' requires the types 'Never' and 'DataTaskError' be equivalent
Run Code Online (Sandbox Code Playgroud)
我可以使用 mapError 并将两个错误都转换为 Error,但我需要一个 DataTaskError 才能创建我的 ViewModelError。
这感觉应该不难,而且它似乎是一个相当常见的用例。我可能只是误解了一些基本原理,将不胜感激。
小智 6
当您的发布者的失败类型为 Never 时,您可以使用 setFailureType(to:)
来匹配另一个发布者的失败类型。请注意,根据文档,此方法只能在故障类型为 Never 时使用。当您有实际的故障类型时,您可以将错误转换为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()
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2039 次 |
最近记录: |