Если вы работали с RxJava / RxKotlin, возможно, вы знакомы с тремя методами подписчика. onNext, onError и onComplete. В реактивном потоке элементы сначала потребляются onNext, а onComplete вызывается, когда поток заканчивается. Если вы столкнетесь с какой-либо ошибкой в ​​onNext, вся наблюдаемая цепочка будет прекращена, и управление будет передано методу onError. Так, например, приведенный ниже код будет работать безупречно и на выходе будет выглядеть так:

Вывод:

1
2
3
4
Completed

Теперь предположим, что мы встретили исключение в onNext, вся наблюдаемая цепочка отбрасывается. В приведенном ниже коде мы намеренно вызываем исключение, когда на входе 2:

Вывод:

1
Exception on 2

Это все хорошо, если вы столкнетесь с ошибкой в ​​подписчике, но что, если вы столкнетесь с ошибкой в ​​одном из операторов над ним? Это может быть оператор map или оператор flatMap. Дело в том, что делать, если вы столкнулись с ошибкой до того, как она дойдет до подписчика? Есть так много вещей, которые мы можем сделать в RxJava, если мы столкнемся с ошибкой. Первое, о чем мы будем говорить, это onExceptionResumeNext ():

onExceptionResumeNext

Чтобы понять это, нам сначала нужно узнать о doOnNext. Вы можете подумать, это очень похоже на onNext подписчика. Верно! doOnNext в основном предназначен для устранения побочных эффектов. Элементы будут отправлены в doOnNext, прежде чем они будут окончательно использованы методом onNext наблюдателя. Итак, doOnNext - отличное место для отладки ваших элементов в потоке. Теперь вернемся к onExceptionResumeNext: если мы обнаружим какое-либо исключение в наблюдаемой цепочке (до того, как они дойдут до методов наблюдателя), мы можем использовать этот метод для подключения другого

наблюдаемый. Давайте посмотрим на приведенный ниже код:

Вывод:

1
10
Complete

В приведенном выше коде мы намеренно вызвали исключение, когда элемент равен 2 (до того, как он будет поглощен наблюдателем) в doOnNext, а когда инициируется исключение, мы подключили другой наблюдаемый Observable.just (10), и это запускает другой поток элементов, который потребляется предыдущим наблюдателем.

Одним из вариантов использования этого может быть механизм отката. Предположим, вы хотите получать последние новости из API, и в случае ошибки (предположим, что сетевое соединение отсутствует) вы можете подключить наблюдаемый объект, который берет данные из вашей локальной базы данных. Таким образом, вы по-прежнему показываете новости (даже если они устарели).

onErrorResumeNext

Он очень похож на onExceptionResumeNext, но предназначен для общей ошибки. onExceptionResumeNext обрабатывает бросаемые объекты java.lang.Exception, а onErrorResumeNext может обрабатывать ошибку типа java.lang.Throwable и java.lang.Error. Ознакомьтесь с изображением ниже, описывающим его работу

doOnError

Этот способ очень похож на doOnNext, поскольку его можно использовать для перехвата ошибки до того, как ошибка дойдет до потребителя. Давайте посмотрим на приведенный ниже пример:

Вывод:

1
Doing on error
Exception on 2

Как видите, блок doOnError был запущен до onError наблюдателя. Так что это отличное место, чтобы сделать кое-что, если вы собираетесь получить ошибку. Это может включать отображение тоста или снэк-бара, информирующего об ошибке.

onErrorReturnItem

Как следует из названия, он просто возвращает значение при обнаружении ошибки. Давайте посмотрим на пример ниже:

Вывод:

1
-1
Complete

Как видите, после ошибки возвращается «-1». Размещение onErrorReturnItem имеет решающее значение. Он должен находиться ниже по течению от того места, где возникает ошибка. Таким образом, в приведенном выше примере, если бы вы поместили onErrorReturnItem перед doOnNext, он не вернул бы «-1» .

onErrorReturn

Иногда вам нужно создать элемент по умолчанию (на случай возникновения ошибки) динамически. Итак, onErrorReturn предоставляет вам throwable и лямбда, которые вы можете использовать для определения возвращаемого значения.

Как и в случае с onErrorReturnItem, положение onErrorReturn также имеет значение. Чтобы попасть в лямбду onErrorReturn, он должен быть ниже по течению от ошибки.

повторить ()

Это еще один способ обработки ошибок. Он просто повторно подписывает предыдущий Observable. Будьте осторожны при использовании этого оператора. Давайте рассмотрим предыдущий пример с оператором retry:

Вывод

1
1
1
1
....(infinite loop)

Как видите, он зашел в бесконечный цикл, поскольку оператор retry повторно подписывается на Observable, который получает исключение на «2».

Чтобы преодолеть эту ситуацию, вы также можете указать число, и попытка повторной попытки будет уменьшена до этого фиксированного числа. Это можно сделать, как показано ниже:

Это уменьшит количество попыток повторной попытки до 3. Существуют и другие варианты, такие как retryUntil, retryWhen, которые очень похожи, поэтому вы можете узнать больше об этом на http: // reactivex .io / документация / операторы / retry.html

Вот другие мои статьи о RxJava, которые могут вам понравиться -