我有一个整数流,我需要使用一个结构来处理,该结构使用CurrentValueSubject
来知道是否允许它进行处理。由于CurrentValueSubject
不完成,如果我在flatMap()
中进行处理,则整个流(fooTheBars
)只有在整数流为空时才能完成。
如果我注解掉处理部分(.flatMap { bar in fooer.doFoo(with: bar) }
),则流会正常完成,因为不涉及CurrentValueSubject
。但我需要它在处理完所有项后正常完成,而不管项的数量。
我看到的输出:
[0, 1, 2]
doing foo with 0
doing foo with 1
doing foo with 2
received value
received value
received value
我想要它输出的内容:
[0, 1, 2]
doing foo with 0
doing foo with 1
doing foo with 2
received value
received value
received value
received completion // hooray, completion!
流为空时的输出(正常完成,这是我想要的):
[]
received completion // hooray, completion!
如果我注解掉处理(.flatMap()
),一切都很好:
[0, 1, 2]
received value
received value
received value
received completion // hooray, completion!
如何修改注解下面的代码,以便在所有项完成处理时完成整个流?像这样使用CurrentValueSubject
是一种固有的错误模式吗?
struct Fooer {
private let readyToFoo = CurrentValueSubject<Bool, Never>(true)
func doFoo(with item: Int) -> AnyPublisher<Void, Never> {
readyToFoo
.filter { $0 }
.map { _ in () }
.handleEvents(receiveOutput: {
print("doing foo with \(item)") // processing
})
.delay(for: .seconds(1), scheduler: DispatchQueue.main)
.eraseToAnyPublisher()
}
}
func getBars() -> AnyPublisher<Int, Never> {
let bars = (0..<(Bool.random() ? 0 : 3))
print(Array(bars))
return bars.publisher
.eraseToAnyPublisher()
}
// can't change anything above this comment
let fooer = Fooer()
let fooTheBars = getBars()
.flatMap { bar in
fooer.doFoo(with: bar)
}
.sink(receiveCompletion: { completion in
print("received completion")
}, receiveValue: { _ in
print("received value")
})
1条答案
按热度按时间mfpqipee1#
如果我理解正确的话,你只想让
doFoo
发布一个值。也就是说,只要doFoo
发布一个值,bar
的“处理”就完成了。因此,您可以通过获取
first()
来停止doFoo
发布服务器。这会产生你想要的输出。如果当你调用
doFoo
时,readyToFoo
恰好持有false
,doFoo
不会发布。只有当readToFoo
发送true
时,doFoo
才会发布它的第一个值。