0

我想用下面的情形 工作,我有两个生产商A和B. producerB只有当producerA成功并执行,如果producerA抛出错误,处理错误,并停在那里应该执行。所以我尝试了这样的事情。当且仅当producerA不会抛出错误时,如何执行producerB?

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

貌似producerB执行即使producerA抛出错误。 请帮助我如何使它适用于我的场景。

+0

地图/ flatMap返回数组。如果它返回错误,你的意思是什么? – user1046037

回答

1

的问题是,究竟是什么,你的意思是用“不抛出一个错误”。

事件上的Signal/SignalProducer该序列具有precisely defined semantic

即使世界的Value(从0 - x)的任意数量的活动,然后,最终,由completedfailedinterrupted事件。之后,没有更多的事件。

一般来说,你可以说,运营商只对value事件进行操作,并立即传播failed事件(而不对其进行操作)。如果你不知道在特定运营商,看看该运营商是关于失败事件的行为非常清晰的文档。


因此,要理解这个问题的方法之一是说producerA成功完成(的value活动的任意号码后),然后开始producerB如果producerA发送failed事件,那就不要。

在这种情况下,运营商then正是你所需要的。它将立即开始producerBproducerA完成,但如果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事件返回一个producerBproducerA每个事件。这里注意,再次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)") 
    })) 
+1

很好的答案。我发现想一想的一个好方法是'flatMapError'基本上用来捕获错误。事实上,它[过去被称为catch](https://github.com/ReactiveCocoa/ReactiveCocoa/commit/e0c266320ba160944eda894210ece7121216f174)。所以你不应该使用它,如果你真的想要错误终止信号链。我会补充一点,如果你不想让整个链错误终止,那么你可以在*'then((producerB)')之后放置'flatMapError' *。 – jjoelson

+0

@MeXx我在第一种方法中看到了一些问题。假设第一个生产者不生产错误,第二个生产者生成错误,它打印该值并且它永远不会进入失败块。 – coolly

+0

@coolly,在'producerA'发送它的值之后,它完成了吗? 'producerB'只会在'producerA'完成后才会启动。如果你想在'producerA'发送一个值时启动'producerB',你应该在'flatMap'中使用第二种方法。 – jjoelson

相关问题