将 Just 与 flatMap 一起使用会产生失败不匹配。结合
Posted
技术标签:
【中文标题】将 Just 与 flatMap 一起使用会产生失败不匹配。结合【英文标题】:Using Just with flatMap produce Failure mismatch. Combine 【发布时间】:2019-12-23 21:54:28 【问题描述】:我有这样的代码
func request(request: URLRequest) -> AnyPublisher<Data, Error>
return Just(request)
.flatMap request in
RequestManager.request(request) // returns AnyPublisher<Data, Error>
.eraseToAnyPublisher()
我收到编译错误:
实例方法 flatMap(maxPublishers:_:) 需要类型 Just.Failure (aka Never) 和 Error 是等价的
很清楚,因为Just
有Never
作为Failure
和.flatMap
需要Error
作为Failure
,所以Never
!= Error
我看到了两种方法:
使用 right Publisher,而不是 Just
,但我没有找到合适的人选。
使用 .mapError
、.mapError $0 as Error
等运算符,但我不确定这是不是个好主意。
有什么方法可以处理吗?
更新:
使用起来更有意义
.setFailureType(to: Error.self)
或
.mapError $0 as Error
【问题讨论】:
【参考方案1】:有特殊运算符setFailureType(to:)
。您可以将故障类型覆盖为您需要的任何错误类型。
func request(request: URLRequest) -> AnyPublisher<Data, Error>
return Just(request)
.setFailureType(to: Error.self)
.flatMap request in
RequestManager.request(request) // returns AnyPublisher<Data, Error>
.eraseToAnyPublisher()
https://developer.apple.com/documentation/combine/just/3343941-setfailuretype
【讨论】:
【参考方案2】:如果您在 Just 输出上调用 .mapError()
,它将更改类型以包含 Error
,但永远不会调用该闭包(所以我不会担心)——除非有人这样做,否则我会这样做一个更好的主意。
通常,flatMap 上的Self.Error == P.Error
是有意义的,因为您不能只忽略来自 Self 的错误。但是,当Self.Error
是Never
时,您可以忽略它们并产生您自己的错误。
【讨论】:
【参考方案3】:虽然公认的答案确实有效,但它非常冗长。我偶然发现了一种更简洁的使用Result<Success,Failure).publisher 的替代语法:
Result.Publisher(.success(request))
(请注意,在这种情况下,我依赖 Swift 来推断错误类型,但您可能需要明确声明它:Result<URLRequest, Error>.Publisher(.success(request))
)
【讨论】:
或者,Result.success(request).publisher
以上是关于将 Just 与 flatMap 一起使用会产生失败不匹配。结合的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Flux<String> 上执行 flatMap() 时获取索引号
将 minHeight 与 flex 一起使用会产生意外的填充