Перехват
восстановление после уведомления onError, продолжая последовательность без ошибки
Оператор Catch перехватывает уведомление onError от исходного Observable и вместо передачи его наблюдателям заменяет его другим элементом или последовательностью элементов, что потенциально позволяет результирующему Observable завершиться нормально или вообще не завершаться.
Существует несколько вариантов оператора Catch, и различные реализации ReactiveX используют различные названия для описания этой операции, как вы можете видеть в разделах ниже.
В некоторых реализациях ReactiveX есть оператор, называемый примерно «OnErrorResumeNext», который ведет себя как вариант Catch: он реагирует на уведомление onError от исходного Observable. В других реализациях оператор с таким названием ведет себя больше как вариант Concat: он выполняет операцию конкатенации независимо от того, завершается исходный Observable нормально или с ошибкой. Это неудобно и запутанно, но с этим приходится смириться.
См. также
Информация, специфичная для языка
RxClojure catch*
RxClojure реализует этот оператор как catch*. Этот оператор принимает два аргумента, оба из которых являются функциями по вашему выбору, которые принимают исключение, поднятое onError, в качестве своего единственного параметра. Первая функция — предикат. Если она возвращает false, catch* передает уведомление onError без изменений своим наблюдателям. Если она возвращает true, то catch* игнорирует ошибку, вызывает вторую функцию (которая возвращает Observable) и передает выдачи и уведомления из этого нового Observable своим наблюдателям.
Вы можете заменить первый параметр функции (предикат, оценивающий исключение) объектом класса, представляющим различные исключения. Если вы сделаете это, catch* будет рассматривать его как эквивалент предикату, который выполняет проверку instance?, чтобы проверить, является ли исключение из уведомления onError экземпляром объекта класса. Другими словами:
Пример кода
(->> my-observable
(catch* IllegalArgumentException
(fn [e] (rx/return 1)))
) эквивалентно:
(->> my-observable
(catch* (fn [e] (-> instance? IllegalArgumentException e))
(fn [e] (rx/return 1)))
)RxCpp
RxCpp не реализует оператор Catch.
RxGroovy onErrorResumeNext onErrorReturn onExceptionResumeNext
RxGroovy реализует оператор Catch таким же образом, как и RxJava. Существует три разных оператора, которые обеспечивают эту функциональность:
onErrorReturn- указывает Observable на выдачу определенного элемента при возникновении ошибки и последующее нормальное завершение
onErrorResumeNext- указывает Observable на начало выдачи последовательности второго Observable при возникновении ошибки
onExceptionResumeNext- указывает Observable на продолжение выдачи элементов после возникновения исключения (но не другого типа исключения)
onErrorReturn
Метод onErrorReturn возвращает Observable, которое отражает поведение исходного Observable, за исключением случаев, когда это Observable вызывает onError, в этом случае вместо распространения этой ошибки наблюдателю, onErrorReturn вместо этого выдает указанный элемент и вызывает метод onCompleted наблюдателя, как показано в следующем примере кода:
Пример кода
def myObservable = Observable.create({ aSubscriber ->
if(false == aSubscriber.isUnsubscribed()) aSubscriber.onNext('Four');
if(false == aSubscriber.isUnsubscribed()) aSubscriber.onNext('Three');
if(false == aSubscriber.isUnsubscribed()) aSubscriber.onNext('Two');
if(false == aSubscriber.isUnsubscribed()) aSubscriber.onNext('One');
if(false == aSubscriber.isUnsubscribed()) aSubscriber.onError();
});
myObservable.onErrorReturn({ return('Blastoff!'); }).subscribe(
{ println(it); }, // onNext
{ println("Error: " + it.getMessage()); }, // onError
{ println("Sequence complete"); } // onCompleted
); Four Three Two One Blastoff! Sequence complete
- Javadoc:
onErrorReturn(Func1)
onErrorResumeNext
Метод onErrorResumeNext возвращает Observable, которое отражает поведение исходного Observable, за исключением случаев, когда это Observable вызывает onError, в этом случае вместо распространения этой ошибки наблюдателю, onErrorResumeNext вместо этого начнет отражать второе резервное Observable, как показано в следующем примере кода:
Пример кода
def myObservable = Observable.create({ aSubscriber ->
if(false == aSubscriber.isUnsubscribed()) aSubscriber.onNext('Three');
if(false == aSubscriber.isUnsubscribed()) aSubscriber.onNext('Two');
if(false == aSubscriber.isUnsubscribed()) aSubscriber.onNext('One');
if(false == aSubscriber.isUnsubscribed()) aSubscriber.onError();
});
def myFallback = Observable.create({ aSubscriber ->
if(false == aSubscriber.isUnsubscribed()) aSubscriber.onNext('0');
if(false == aSubscriber.isUnsubscribed()) aSubscriber.onNext('1');
if(false == aSubscriber.isUnsubscribed()) aSubscriber.onNext('2');
if(false == aSubscriber.isUnsubscribed()) aSubscriber.onCompleted();
});
myObservable.onErrorResumeNext(myFallback).subscribe(
{ println(it); }, // onNext
{ println("Error: " + it.getMessage()); }, // onError
{ println("Sequence complete"); } // onCompleted
); Three Two One 0 1 2 Sequence complete
- Javadoc:
onErrorResumeNext(Func1) - Javadoc:
onErrorResumeNext(Observable)
onExceptionResumeNext
Подобно методу onErrorResumeNext, это возвращает Observable, которое отражает поведение исходного Observable, за исключением случаев, когда это Observable вызывает onError, в этом случае, если Throwable, переданный onError, является Exception, вместо распространения этого Exception наблюдателю, onExceptionResumeNext вместо этого начнет отражать второе резервное Observable. Если Throwable не является Exception, Observable, возвращаемое onExceptionResumeNext, распространит его на метод onError своего наблюдателя и не вызовет своего резервного Observable.
- Javadoc:
onExceptionResumeNext(Observable)
RxJava 1․x onErrorResumeNext onErrorReturn onExceptionResumeNext
RxJava реализует оператор Catch с тремя различными операторами:
onErrorReturn- указывает Observable на выдачу определенного элемента при возникновении ошибки и последующее нормальное завершение
onErrorResumeNext- указывает Observable на начало выдачи последовательности второго Observable при возникновении ошибки
onExceptionResumeNext- указывает Observable на продолжение выдачи элементов после возникновения исключения (но не другого типа исключения)
onErrorReturn
Метод onErrorReturn возвращает Observable, которое отражает поведение исходного Observable, за исключением случаев, когда это Observable вызывает onError, в этом случае вместо распространения этой ошибки наблюдателю, onErrorReturn вместо этого выдает указанный элемент и вызывает метод onCompleted наблюдателя.
- Javadoc:
onErrorReturn(Func1)
onErrorResumeNext
Метод onErrorResumeNext возвращает Observable, которое отражает поведение исходного Observable, за исключением случаев, когда это Observable вызывает onError, в этом случае вместо распространения этой ошибки наблюдателю, onErrorResumeNext вместо этого начнет отражать второе резервное Observable.
- Javadoc:
onErrorResumeNext(Func1) - Javadoc:
onErrorResumeNext(Observable)
onExceptionResumeNext
Подобно методу onErrorResumeNext , это возвращает Observable, которое отражает поведение исходного Observable, за исключением случаев, когда это Observable вызывает onError, в этом случае, если Throwable, переданный onError, является Exception, вместо распространения этого Exception наблюдателю, onExceptionResumeNext вместо этого начнет отражать второе резервное Observable. Если Throwable не является Exception, Observable, возвращаемое onExceptionResumeNext, распространит его на метод onError своего наблюдателя и не вызовет своего резервного Observable.
- Javadoc:
onExceptionResumeNext(Observable)
RxJS catch onErrorResumeNext
RxJS реализует оператор Catch с двумя различными операторами:
catch- указывает Observable на начало выдачи последовательности второго Observable при возникновении ошибки
onErrorResumeNext- указывает Observable на начало выдачи последовательности второго Observable при возникновении ошибки или при нормальном завершении исходного Observable
catch
catch встречается в следующих распределениях:
rx.jsrx.all.jsrx.all.compat.jsrx.compat.jsrx.lite.jsrx.lite.compat.js
onErrorResumeNext
Эта реализация заимствует запутанную номенклатуру из Rx.NET, в которой onErrorResumeNext переключается на резервное Observable как при ошибке, так и при нормальном, без ошибок завершении исходного Observable.
onErrorResumeNext встречается в следующих распределениях:
rx.jsrx.compat.js
RxKotlin onErrorResumeNext onErrorReturn onExceptionResumeNext
RxKotlin реализует оператор Catch таким же образом, как и RxJava. Существует три различных оператора, предоставляющих эту функциональность:
onErrorReturn- указывает Observable на отправку определенного элемента при обнаружении ошибки, а затем на нормальное завершение
onErrorResumeNext- указывает Observable на начало отправки последовательности второго Observable при обнаружении ошибки
onExceptionResumeNext- указывает Observable на продолжение отправки элементов после обнаружения исключения (но не другого типа исключения)
onErrorReturn
Метод onErrorReturn возвращает Observable, отражающий поведение исходного Observable, если только этот Observable не вызовет onError, в этом случае вместо распространения этой ошибки наблюдателю onErrorReturn отправит указанный элемент и вызовет метод onCompleted наблюдателя.
onErrorResumeNext
Метод onErrorResumeNext возвращает Observable, отражающий поведение исходного Observable, если только этот Observable не вызовет onError, в этом случае вместо распространения этой ошибки наблюдателю onErrorResumeNext начнёт отражать поведение второго резервного Observable.
onExceptionResumeNext
Подобно методу onErrorResumeNext, этот метод возвращает Observable, отражающий поведение исходного Observable, если только этот Observable не вызовет onError, в этом случае, если Throwable, переданный onError, является исключением, вместо распространения этого исключения наблюдателю onExceptionResumeNext начнёт отражать поведение второго резервного Observable. Если Throwable не является исключением, Observable, возвращаемый onExceptionResumeNext, распространит его методу наблюдателя onError и не вызовет резервное Observable.
RxNET Catch OnErrorResumeNext
Rx.NET реализует оператор Catch с двумя различными операторами:
Catch- указывает Observable на начало отправки последовательности второго Observable при обнаружении ошибки
OnErrorResumeNext- указывает Observable на начало отправки последовательности второго Observable при обнаружении ошибки или при нормальном завершении исходного Observable
Catch
Оператор Catch имеет вариант, позволяющий указать тип исключения, которое нужно перехватить. Если вы используете этот вариант оператора, любые другие исключения будут переданы наблюдателю так, как будто оператор Catch не был применён.
OnErrorResumeNext
Это реализация вводит запутанную терминологию, в которой, несмотря на своё название, оператор OnErrorResumeNext переключается на резервное Observable как при ошибке, так и при нормальном, без ошибок, завершении исходного Observable. Поэтому он больше похож на оператор конкатенации.
RxPHP catch
RxPHP реализует этот оператор как catch.
Продолжает последовательность observable, которая завершается исключением, с помощью следующей последовательности observable.
Пример кода
//from https://github.com/ReactiveX/RxPHP/blob/master/demo/catch/catch.php
$obs2 = Rx\Observable::of(42);
$source = \Rx\Observable::error(new Exception('Some error'))
->catch(function (Throwable $e, \Rx\Observable $sourceObs) use ($obs2) {
return $obs2;
});
$subscription = $source->subscribe($stdoutObserver); Next value: 42 Complete!
RxPY catch_exception on_error_resume_next
RxPY реализует оператор Catch с двумя различными операторами:
catch_exception- указывает Observable, если он обнаруживает ошибку, начать отправку элементов из набора других Observable, по одному Observable за раз, пока одно из этих Observable не завершится успешно
on_error_resume_next- указывает Observable на конкатенацию элементов, отправленных набором других Observable, по одному Observable за раз, независимо от того, завершается ли исходное Observable или любое последующее Observable с ошибкой
catch_exception
Вы можете передать catch_exception набор резервных Observable в качестве отдельных параметров функции или в виде одного массива Observable. Если он встречает уведомление onError от исходного Observable, он подпишется и начнёт отражать первое из этих резервных Observable. Если это резервное Observable само выдаёт уведомление onError, catch_exception проигнорирует его и переключится на следующее резервное Observable. Если любое из этих Observable выдаёт уведомление onCompleted, catch_exception передаст это уведомление и остановится.
on_error_resume_next
Вы можете передать on_error_resume_next набор резервных Observable в качестве отдельных параметров функции, как один массив Observable или как функцию-генератор Observable. Когда исходное Observable завершается, будь то нормально или с ошибкой, on_error_resume_next подпишется и начнёт отражать первое из этих резервных Observable, а затем рекурсивно продолжит этот процесс конкатенации для каждого дополнительного Observable, пока не закончатся Observable для отражения, в этот момент он передаст уведомление onError или onCompleted от последнего из этих Observable.
Rxrb on_error_resume_next rescue_error
Rx.rb реализует оператор Catch с двумя различными операторами:
rescue_error- указывает Observable на начало отправки элементов из другого Observable или из Observable, возвращаемого действием, если обнаруживается ошибка
on_error_resume_next- указывает Observable на конкатенацию элементов, отправленных другим Observable, с последовательностью, отправленной исходным Observable, независимо от того, завершается ли исходное Observable нормально или с ошибкой
rescue_error
Вы можете передать rescue_error либо Observable, либо функцию-генератор Observable.
on_error_resume_next
В Rx.rb оператор on_error_resume_next унаследовал вводящую в заблуждение терминологию от Rx.NET, в которой он конкатенирует вторую последовательность Observable к исходной последовательности, независимо от того, завершается ли эта исходная последовательность нормально или с ошибкой.
RxScala onErrorFlatMap onErrorResumeNext onErrorReturn onExceptionResumeNext
Rx.rb реализует оператор Catch с четырьмя различными операторами:
onErrorFlatMap- заменяет все
onErrorуведомления от плохо работающего Observable на эмиссии из вторичного Observable onErrorResumeNext- инструктирует Observable начать эмиссию последовательности второго Observable, если он столкнётся с ошибкой
onErrorReturn- инструктирует Observable сгенерировать определённый элемент при возникновении ошибки, а затем завершиться нормально
onExceptionResumeNext- инструктирует Observable продолжать эмиссию элементов после возникновения исключения (но не другого типа исключения)
onErrorFlatMap
onErrorFlatMap обрабатывает особый случай: источник Observable, который не соответствует контракту Observable таким образом, что он может чередовать onError уведомления со своими эмиссиями, не завершаясь. Этот оператор позволяет вам заменить эти onError уведомления эмиссиями Observable по вашему выбору без отписки от источника, так что любые будущие элементы, выпущенные источником, будут переданы наблюдателям, как если бы последовательность не была прервана onError уведомлением.
Поскольку onErrorFlatMap предназначен для работы с патологическими источниками Observable, которые не завершаются после выдачи ошибки, он в основном полезен в сценариях отладки/тестирования.
Обратите внимание, что вы должны применить onErrorFlatMap непосредственно к патологическому источнику Observable, а не к этому Observable после его модификации дополнительными операторами, так как такие операторы могут фактически нормализовать источник Observable, отписавшись от него сразу после выдачи ошибки. Например, выше показано, как onErrorFlatMap отреагирует на два генерирующих ошибку Observable, которые были объединены оператором Merge:
Обратите внимание, что onErrorFlatMap не отреагирует на обе ошибки, сгенерированные обоими Observable, а только на единственную ошибку, переданную merge.
onErrorResumeNext
Метод onErrorResumeNext возвращает Observable, которое отражает поведение исходного Observable, за исключением случаев, когда это Observable вызывает onError, в этом случае, вместо передачи этой ошибки наблюдателю, onErrorResumeNext начнет отражать второе, резервное Observable.
onErrorReturn
Метод onErrorReturn возвращает Observable, которое отражает поведение исходного Observable, за исключением случаев, когда это Observable вызывает onError, в этом случае, вместо передачи этой ошибки наблюдателю, onErrorReturn вместо этого выведет указанный элемент и вызовет метод onCompleted наблюдателя.
onExceptionResumeNext
Подобно методу onErrorResumeNext, он возвращает Observable, которое отражает поведение исходного Observable, за исключением случаев, когда это Observable вызывает onError, в этом случае, если Throwable, переданный в onError, является исключением, вместо передачи этого исключения наблюдателю, onExceptionResumeNext вместо этого начнет отражать второе, резервное Observable. Если Throwable не является исключением, Observable, возвращаемое onExceptionResumeNext, передаст его методу onError наблюдателя и не вызовет резервное Observable.
© ReactiveX contributors
Licensed under the Apache License 2.0.
http://reactivex.io/documentation/operators/catch.html