0

我有一个信号生产者,当它终止时我想知道是否发送了一个值,我只需要最后一个,看起来很简单......

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()

但是有时在调用 value 时调用了 terminate ,但 myValue 仍然是 nil ...

4

2 回答 2

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这里使用a,所以我可以手动向它发送事件以进行演示,同样适用SignalProducer

注意:如果我们发送interrupted一个failed事件,最后一个值 3将不会被发送,因为那些终止事件会使正常流程短路。

如果您SignalProducer可能失败,并且您仍想获得失败前的最后一个值,则可以使用flatMapError忽略运算符之前的错误last

signal
  .flatMapError { _ in
    return .empty
  }
  .take(last: 1)
  .observe(observer)
于 2018-05-04T08:53:04.013 回答
-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
})
于 2018-05-03T11:18:34.940 回答