当且仅当producerA没有抛出错误时,如何执行producerB?

问题描述 投票:0回答:2

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

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

看起来producerB执行即使producerA抛出错误。请帮助我如何使其与我的方案一起使用。

ios swift reactive-programming reactive-cocoa reactive-swift
2个回答
1
投票

问题是,你的意思是“不抛出错误”。

Signal / SignalProducer上的事件序列有一个precisely defined semantic

这是一个任意数量的Value(来自0 - x)事件,最后是completedfailedinterrupted事件。之后就没有更多的活动了。

通常你可以说大多数操作符只对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事件中使用producerAproducerB上的每个事件返回一个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)")
  }))

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

© www.soinside.com 2019 - 2024. All rights reserved.