我正在尝试使用下面的场景我有两个生成器A和B.producerB
应该只在producerA
执行成功时执行,如果producerA
抛出错误,处理错误并停在那里。所以我尝试过这样的事情。
producerA.flatMapError {
// handle error and stop right here
}.then(producerB).startWithResult {
// ...
}
看起来producerB
执行即使producerA
抛出错误。请帮助我如何使其与我的方案一起使用。
问题是,你的意思是“不抛出错误”。
Signal
/ SignalProducer
上的事件序列有一个precisely defined semantic
这是一个任意数量的Value
(来自0 - x)事件,最后是completed
,failed
或interrupted
事件。之后就没有更多的活动了。
通常你可以说大多数操作符只对value
事件进行操作并立即传播failed
事件(不对它们进行操作)。如果您不确定某个特定的操作员,请查看该操作员的文档,该文档非常清楚故障事件的行为。
因此,理解这个问题的一种方法是说当producerA
成功完成时(在任意数量的value
事件之后),然后启动producerB
并且如果producerA
发送failed
事件,则不要。
在这种情况下,then
运算符正是您所需要的。一旦producerB
完成,它将启动producerA
,但如果producerA
失败则不会!
producerA.then(producerB)
.start(Signal.Observer(value: { value in
print("Value \(value)")
}, failed: {error in
print("Error \(error)")
}))
注意,你不想在这里使用flatMapError
,因为那会(根据你在块中的错误处理方式看起来)将failed
事件转换为value
最终会触发producerB
的事件。
理解这个问题的另一种方法是说producerA
上的每个事件都不是错误应该触发producerB
一次
在这种情况下,你会在flatMap
事件中使用producerA
为producerB
上的每个事件返回一个producerA
。请注意,flatMap
再次传播failed
事件,因此failed
上的producerA
事件将导致整个链失败而不执行producerB
producerA.flatMap(.concat) { _ in return producerB }
.start(Signal.Observer(value: { value in
print("Value \(value)")
}, failed: {error in
print("Error \(error)")
}))
试试这个:
func scenario() -> SignalProducer<MyValueType, MyErrorType> {
return SignalProducer { observer, _ in
producerA.startWithResult({ (res) in
switch res {
case .success(let value):
observer.send(value: value)
observer.sendCompleted()
case .failure(let error):
print(error)//handle your error here
observer.send(error: err)
}
})
}.then(producerB)
}
scenario().start()
您可以创建自定义SignalProducer并通过告知观察者根据您的方案进行操作来定义所需的行为。