ReactiveSwift: повторите попытку до n раз, затем выполните некоторый код

Рассмотрим код ниже

func test() -> SignalProducer<String, Error> {
    return SignalProducer<String, Error> { observer, _ in
        ...
    }
}

test()
    .on(value: { s in
        print(s)
    })
    .retry(upTo: 2)
    .start()
}

Есть ли встроенный способ повторить попытку n раз, а затем (если все попытки не увенчались успехом) выполнить какой-либо обратный вызов?

Конечно, можно ввести локальный счетчик и считать ошибки в .on(failed: _), а затем что-то делать, если счетчик равен n+1, но есть ли другой способ сделать это?


person Buddy    schedule 25.04.2017    source источник


Ответы (1)


retry(upTo:) передает сообщение об ошибке после достижения предела повторных попыток, поэтому вы можете использовать один из методов start, который позволяет обрабатывать значения и ошибку. Например, используя startWithResult, вы можете сделать это (обратите внимание, я не тестировал этот код, но он должен дать вам представление):

test()
    .retry(upTo: 2)
    .startWithResult { result in
        switch result {
        case let .success(value):
            print(value)
        case let .failed(error):
            // handle error here
        }
    }
person jjoelson    schedule 27.04.2017
comment
Здесь важен порядок: добавление .retry до того, как обработчики .on передают только последнюю ошибку (в данном случае желаемый эффект). Я как-то пропустил это. - person Buddy; 28.04.2017
comment
Да, каждый оператор на самом деле создает новый сигнал/производитель, который оборачивает предыдущий с некоторой логикой или трансформацией. Таким образом, retry в вашем исходном коде будет повторять попытку производителя, как это определено всем предшествующим кодом, который включает on побочные эффекты. - person jjoelson; 28.04.2017