当发布者失败类型不等效时如何使用 CombineLatest?
How to use CombineLates when when publishers failure types is not equivalent?
我有两个函数 return AnyPublisher 具有不同的故障类型:Never 和 Error。在 CombineLates 中使用这些函数时,编译会失败并出现错误:Generic struct 'CombineLatest' requires the types 'Error' and 'Never'等价
永不失败的功能:
func foo() -> AnyPublisher<Int, Never> {
Result<Int, Never>
.success(1).publisher
.eraseToAnyPublisher()
}
有时会失败的功能:
func boo() -> AnyPublisher<Int, Error> {
Result<Int, Error>
.failure(NSError(domain: "d", code: -1))
.publisher.eraseToAnyPublisher()
}
foo & boo 函数用法:
Publishers.CombineLatest(foo(), boo())
产生错误:
Generic struct 'CombineLatest' requires the types 'Error' and 'Never' be equivalent
发布者失败类型不等时如何使用CombineLates?
您可以使用 setFailureType(to:)
设置永不失败的发布者的错误类型,以匹配其他失败的发布者:
func foo() -> AnyPublisher<Int, Never> {
Result<Int, Never>
.success(1).publisher
.setFailureType(to: Error.self)
.eraseToAnyPublisher()
}
如果您不想更改 foo
,您也可以在 foo
的 return 值上调用 setFailureType
:
Publishers.CombineLatest(
foo().setFailureType(to: Error.self).eraseToAnyPublisher(),
boo()
)
每当您需要在 Combine 中匹配失败类型时,对于 Never
失败类型,例如 Just
发布者,您将使用 setFailureType(to:)
:
let p: AnyPublisher<Int, Never> = ...
let p1 = p.setFailureType(to: Error.self)
.eraseToAnyPublisher() // AnyPublisher<Int, Error>
对于非 Never
失败,您需要使用 .mapError
:
let p2 = p1.mapError { CustomError(wrapping: [=11=]) }
.eraseToAnyPublisher() // AnyPublisher<Int, CustomError>
所以,在你的情况下,如果你想改变 foo
的 return 值,你会做:
func foo() -> AnyPublisher<Int, Never> {
Result<Int, Never>
.success(1).publisher
.setFailureType(to: Error.self)
.eraseToAnyPublisher()
}
如果你不想改变foo
,但仍然使用withbar
,你可以这样做:
Publishers.CombineLatest(foo().setFailureType(to: Error.self), boo())
.map { (f, b) in
// f and b are Ints, as emitted by foo and bar, respectively
}
我有两个函数 return AnyPublisher 具有不同的故障类型:Never 和 Error。在 CombineLates 中使用这些函数时,编译会失败并出现错误:Generic struct 'CombineLatest' requires the types 'Error' and 'Never'等价
永不失败的功能:
func foo() -> AnyPublisher<Int, Never> {
Result<Int, Never>
.success(1).publisher
.eraseToAnyPublisher()
}
有时会失败的功能:
func boo() -> AnyPublisher<Int, Error> {
Result<Int, Error>
.failure(NSError(domain: "d", code: -1))
.publisher.eraseToAnyPublisher()
}
foo & boo 函数用法:
Publishers.CombineLatest(foo(), boo())
产生错误:
Generic struct 'CombineLatest' requires the types 'Error' and 'Never' be equivalent
发布者失败类型不等时如何使用CombineLates?
您可以使用 setFailureType(to:)
设置永不失败的发布者的错误类型,以匹配其他失败的发布者:
func foo() -> AnyPublisher<Int, Never> {
Result<Int, Never>
.success(1).publisher
.setFailureType(to: Error.self)
.eraseToAnyPublisher()
}
如果您不想更改 foo
,您也可以在 foo
的 return 值上调用 setFailureType
:
Publishers.CombineLatest(
foo().setFailureType(to: Error.self).eraseToAnyPublisher(),
boo()
)
每当您需要在 Combine 中匹配失败类型时,对于 Never
失败类型,例如 Just
发布者,您将使用 setFailureType(to:)
:
let p: AnyPublisher<Int, Never> = ...
let p1 = p.setFailureType(to: Error.self)
.eraseToAnyPublisher() // AnyPublisher<Int, Error>
对于非 Never
失败,您需要使用 .mapError
:
let p2 = p1.mapError { CustomError(wrapping: [=11=]) }
.eraseToAnyPublisher() // AnyPublisher<Int, CustomError>
所以,在你的情况下,如果你想改变 foo
的 return 值,你会做:
func foo() -> AnyPublisher<Int, Never> {
Result<Int, Never>
.success(1).publisher
.setFailureType(to: Error.self)
.eraseToAnyPublisher()
}
如果你不想改变foo
,但仍然使用withbar
,你可以这样做:
Publishers.CombineLatest(foo().setFailureType(to: Error.self), boo())
.map { (f, b) in
// f and b are Ints, as emitted by foo and bar, respectively
}