Как выполнить 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 и определяете желаемое поведение, приказывая наблюдателю действовать в соответствии с вашим сценарием.

Другие вопросы по тегам