Как выполнить providerB тогда и только тогда, когда производитель A не выдаст ошибку?
Я пытаюсь работать с приведенным ниже сценарием, у меня есть два производителя A и B.producerB
должен выполняться только тогда, когда producerA
выполняется успешно, а также, если producerA
выдает ошибку, обрабатывает ошибку и останавливается на этом. Поэтому я попробовал что-то подобное.
producerA.flatMapError {
// handle error and stop right here
}.then(producerB).startWithResult {
// ...
}
Похоже producerB
выполняется, даже если producerA
выдает ошибку. Пожалуйста, помогите мне, как я могу заставить это работать с моим сценарием.
2 ответа
Вопрос в том, что именно вы подразумеваете под словом "не выдает ошибку".
Последовательность событий на Signal
/ SignalProducer
имеет точно определенную семантику
Theres произвольное количество 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 и определяете желаемое поведение, приказывая наблюдателю действовать в соответствии с вашим сценарием.