我有一个信号发生器,当它终止时我想知道是否发送了一个值,我只需要最后一个,看起来很简单......
let myProducer: SignalProducer<MyObject, MyError> = getMyProducer()
myProducer.on(terminated: {
// I need the last value here
// Or I need to know if value was never called
}).start()
我试图将值存储在本地var:
中let myProducer: SignalProducer<MyObject, MyError> = getMyProducer()
var myValue: MyObject?
myProducer.on(value: { value in
myValue = value
}, terminated: {
guard let value = myValue else {
// value was never called
return
}
// value was called
}).start()
但有时终止会在调用值时调用,但myValue仍然是nil ......
答案 0 :(得分:1)
首先,您确定要进行terminated
事件吗?
在正常情况下,事件流以completed
事件结束。发生故障时的例外情况为failed
,interrupted
,当流程正常完成(例如取消)之前观察结束时。
第二:你的SignalProducer
能否失败,而在失败的情况下,你是否还想在失败前发送最后一个值?
如果没有,它就像使用take(last:)
运算符一样简单:
enum MyError: Error {
case testError
}
let (signal, input) = Signal<Int, MyError>.pipe()
let observer = Signal<Int, MyError>.Observer(
value: { print("value: \($0)") },
failed: { print("error: \($0)") },
completed: { print("completed") },
interrupted: { print("interrupted") }
)
signal
.take(last: 1)
.observe(observer)
input.send(value: 1) // Nothing printed
input.send(value: 2) // Nothing printed
input.send(value: 3) // Nothing printed
input.sendCompleted() // value 3 printed
我在这里使用Signal
因此我可以手动向其发送事件仅用于演示,同样适用于SignalProducer
。
注意:如果我们发送interrupted
或failed
事件,最后一个值3 将不会发送,因为那些终止事件会使正常流程短路。
如果您的SignalProducer
可能失败,并且您仍希望在失败前获得最后一个值,则可以使用flatMapError
忽略错误 {{1运营商:
last
答案 1 :(得分:-1)
我的回答:
producer
.flatMapError { _ in SignalProducer<Value, NoError>.empty }
.collect()
startWithResult( { result in
case let .success(results):
done(with: results.last)
case let .failure(error):
() // should not happen as errors are flatmapped
})