0

我正在尝试使用以下场景,我有两个生产者 A 和 B。 producerB应该仅在producerA成功执行时执行,并且如果producerA抛出错误,则处理错误并停在那里。所以我尝试了这样的事情。

producerA.flatMapError {
    // handle error and stop right here 
}.then(producerB).startWithResult { 
    // ...
}

看起来producerB即使producerA抛出错误也会执行。请帮助我如何使它适用于我的场景。

4

2 回答 2

1

问题是,确切地说,“不抛出错误”是什么意思。

Signal/上的事件序列SignalProducer具有精确定义的语义

有任意数量的Value(从 0 - x)事件,最后是 a或completedEvent 。之后就没有更多的事件了。failedinterrupted

一般来说,您可以说大多数运算符仅对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


理解这个问题的另一种方法是说不是错误的每个事件都应该触发一次producerAproducerB

在这种情况下,您将使用flatMapon 事件为上的每个事件producerA返回一个。再次注意,这里会立即传播一个事件,所以一个事件 on会导致整个链失败而不执行producerBproducerAflatMapfailedfailedproducerAproducerB

producerA.flatMap(.concat) { _ in return producerB }
  .start(Signal.Observer(value: { value in
    print("Value \(value)")
  }, failed: {error in
    print("Error \(error)")
  }))
于 2017-10-05T10:44:16.500 回答
0

尝试这个:

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 并通过告诉观察者根据您的场景进行操作来定义所需的行为。

于 2018-09-14T09:12:19.087 回答