我有一个异步发送Int
SignalProducer
producer
。我可以将值求和
producer.scan(0, +)
假设我想将总和重置为0
如果它是> 10
并且 1 秒内没有发送其他值。我的第一次尝试看起来像这样:
producer
.scan(0, +)
.flatMap(.latest) { n -> SignalProducer<Int, NoError> in
if n <= 10 {
return SignalProducer(value: n)
} else {
return SignalProducer.merge([
SignalProducer(value: n),
SignalProducer(value: 0).delay(1, on: QueueScheduler.main)
])
}
}
虽然这会正确发送0
,但它不会重置scan
中的状态。也就是说,一系列9, 8, long pause, 7
发送9, 17, 0, 24
.
有没有办法以一种正确重置状态的方式将这两个概念结合起来?
我会使用startWithSignal
来访问生成的Signal
,以便创建一个重置触发器以与传入的值合并。我使用枚举作为我的值来指示进入scan
的值是重置触发器还是累积Int
。
enum ValOrReset {
case val(Int)
case reset
}
producer.startWithSignal { signal, _ in
resetTrigger = signal
.debounce(TimeInterval(1.0), on: QueueScheduler.main)
.map { _ in .reset }
signal
.map { val in .val(val) }
.merge(with: resetTrigger)
.scan(0) { (state, next) in
switch next {
case .val(let val):
return state + val
case .reset:
if state > 10 {
return 0
}
else {
return state
}
}
}
.observeValues { val in
print(val)
}
}
startWithSignal
的工作方式是,它确保在闭包完成之前不会有值出现,这意味着您可以创建多个下游信号并将它们连接在一起,而不必担心丢失任何值,即使生产者同步发送值也是如此。