合并:Just 和 first() 之间完成流的区别
Combine: difference between Just and first() to finish a stream
我是 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, 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)
.timeout(.seconds(5), scheduler: DispatchQueue.main)
.eraseToAnyPublisher()
}
使用 getPublisherWithFlatMap
时,我的流没有完成(触发超时),即使返回 Just
发布者并且它应该完成。为什么?
“问题”是由于您使用 PassthroughSubject
作为您的上游造成的。 PassthroughSubject
永远不会完成,除非您明确发送完成。
当使用 first
时,上游是否完成并不重要,因为 first
在其上游发出单个值后立即完成。但是,在 flatMap
的情况下,flatMap
对其上游发出的每个值执行闭包,因此它仅在其上游完成时才完成。 return Just
在 flatMap
中并不重要,Just
只会被 return 编辑为单个值,而不是上游作为一个整体。
如果你想确保 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()
}
我是 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, 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)
.timeout(.seconds(5), scheduler: DispatchQueue.main)
.eraseToAnyPublisher()
}
使用 getPublisherWithFlatMap
时,我的流没有完成(触发超时),即使返回 Just
发布者并且它应该完成。为什么?
“问题”是由于您使用 PassthroughSubject
作为您的上游造成的。 PassthroughSubject
永远不会完成,除非您明确发送完成。
当使用 first
时,上游是否完成并不重要,因为 first
在其上游发出单个值后立即完成。但是,在 flatMap
的情况下,flatMap
对其上游发出的每个值执行闭包,因此它仅在其上游完成时才完成。 return Just
在 flatMap
中并不重要,Just
只会被 return 编辑为单个值,而不是上游作为一个整体。
如果你想确保 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()
}