如何解决结合:Just 和 first() 之间的区别来完成一个流
我是 Combine 的新手,我不了解这些情况下的行为:
func getPublisherWithFirst() -> AnyPublisher<Value,Error> {
// somePublisher: PassthroughSubject<Bool,Never>
return somePublisher
.compactMap { (someBool) -> Value? in
if someBool {
return Value()
}
return nil
}
.setFailureType(to: Error.self)
.first()
.timeout(.seconds(5),scheduler: dispatchQueue.main)
.erasetoAnyPublisher()
}
func getPublisherWithFlatMap() -> AnyPublisher<Value,Never>
return somePublisher
.flatMap { (someBool) -> AnyPublisher<Value,Never> in
if someBool {
return Just(Value()).erasetoAnyPublisher()
}
return Empty(completeImmediately: false,outputType: Value.self,failureType: Never.self).erasetoAnyPublisher()
}
.setFailureType(to: Error.self)
.timeout(.seconds(5),scheduler: dispatchQueue.main)
.erasetoAnyPublisher()
}
使用 getPublisherWithFlatMap
时,我的流不会结束(触发超时),即使返回了 Just
发布者并且它应该结束。为什么?
解决方法
“问题”是由您使用 PassthroughSubject
作为上游引起的。 PassthroughSubject
永远不会完成,除非您明确发送完成。
使用 first
时,上游是否完成并不重要,因为只要 first
的上游发出单个值,它就会完成。但是,在 flatMap
的情况下,flatMap
对其上游发出的每个值执行其闭包,因此它仅在其上游完成时完成。您在 Just
中返回 flatMap
无关紧要,Just
只会返回单个值,而不是整个上游。
如果您想确保 getPublisherWithFlatMap
在发出单个值后也完成,您也应该对其调用 first
,类似于 getPublisherWithFirst
。
func getPublisherWithFlatMap() -> AnyPublisher<Value,Error> {
// somePublisher: PassthroughSubject<Bool,Never>
return somePublisher
.flatMap { (someBool) -> AnyPublisher<Value,Never> in
if someBool {
return Just(Value()).eraseToAnyPublisher()
}
return Empty(completeImmediately: false,outputType: Value.self,failureType: Never.self).eraseToAnyPublisher()
}
.setFailureType(to: Error.self)
.first()
.timeout(.seconds(5),scheduler: DispatchQueue.main)
.eraseToAnyPublisher()
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。