【发布时间】:2015-11-11 07:23:07
【问题描述】:
ReactiveCocoa 4 在 SignalProducer 类上有一个方法 then 等待生产者完成并用另一个生产者替换它,如下所示:
someProducer.then(replacementProducer).
但是我想要的是一种方法,它等到原始生产者出错,然后用第二个生产者替换它(对完成事件不做任何事情)。
then 实现为(注意不转发下一个事件):
public func then<U>(replacement: SignalProducer<U, Error>) -> SignalProducer<U, Error> {
let relay = SignalProducer<U, Error> { observer, observerDisposable in
self.startWithSignal { signal, signalDisposable in
observerDisposable.addDisposable(signalDisposable)
signal.observe { event in
switch event {
case let .Failed(error):
observer.sendFailed(error)
case .Completed:
observer.sendCompleted()
case .Interrupted:
observer.sendInterrupted()
case .Next:
break
}
}
}
}
return relay.concat(replacement)
}
除了失败之外,我想要的看起来很相似,它不会发送错误,而是发送完成的信号。更具体地说,switch 语句将更改为:
signal.observe { event in
switch event {
case .Failed:
observer.sendCompleted()
case .Completed, .Next: break
case .Interrupted:
observer.sendInterrupted()
}
}
}
我的问题如下:
1) 这有效吗?它按我的预期工作,替换信号仅在第一个信号出错时启动。 2) 有没有更好的方法让错误信息不丢失?
我会使用它的一个例子是两步验证过程:
self.verifyToken(token).failed(self.revalidateSession())
如果令牌验证成功,则一切正常,无需重新验证。如果失败,则需要重新验证。
编辑:
我更改了信号观察块,以便如果第一个信号完成且没有错误,它会以 startWithComplete 开始替换信号,以便完成事件沿链向下转发,而不会触发信号的任何操作。
这样做很容易:
self.verify(token).failed(self.refreshSession(token)).then(self.fetchUserForToken(token))
其中then 被链接,并且仅在verify 或refreshSession 成功时执行。
signal.observe { event in
switch event {
case .Failed:
observer.sendCompleted()
case .Completed:
replacement.startWithCompleted {}
case .Next: break
case .Interrupted:
observer.sendInterrupted()
}
}
}
【问题讨论】:
标签: swift reactive-cocoa