#angular #typescript #error-handling #rxjs
Вопрос:
В RxJS представлено множество способов обработки ошибок, и мне трудно понять каждый из них и то, где они используются. Чем больше я узнаю о RxJS, тем меньше я его понимаю.
Если я использую трубу, есть ошибка.
Если я использую кран внутри трубы, есть необязательный параметр ошибки.
Если я использую подписку, есть также необязательный параметр ошибки.
Где я хочу использовать один обработчик ошибок вместо другого? Каковы варианты использования необязательных параметров ошибок? Если я использую параметр ошибки tap, нужно ли мне все еще использовать catchError? Если у меня есть ошибка catchError, нужно ли мне по-прежнему использовать параметр ошибки подписки?
Я хочу лучше понять каждый из обработчиков ошибок и то, как правильно обрабатывать ошибки.
Ответ №1:
Обработка ошибки с помощью обратного вызова ошибки подписки может выполнить вашу работу, но у нее есть ограничения на случай, если вы захотите выдать альтернативное значение в случае ошибки. (восстановительная стоимость)
Например, представьте, что вы ждете, пока ваш наблюдаемый выдаст список пользователей, но вы хотите получить пустой массив в случае ошибки, вы не можете сделать это в обратном вызове ошибки внутри вашего вызова подписки, но вы можете сделать это с помощью catchError
getUsers$.pipe( catchError(error =gt; of([])) )
Вы используете оператор multple catchError, чтобы выдать ошибку и добавить значение замены
getUsers$.pipe( catchError(error =gt; { return throwError(error); }), catchError(error =gt; { return of([]); }) ).subscribe( users=gt; console.log('users', users), err =gt; console.log('Error', err), )
в этом случае возникшая ошибка никогда не достигнет функции обработчика подписки, это будет указано в журнале вашей консоли
users []
Ответ №2:
Потоки RxJS спроектированы таким образом, что ошибка приводит к свертыванию всего потока. Чтобы предотвратить такое поведение, RxJS предоставляет catchError
оператора. Он просто ловит ошибку; входной поток catchError свернут, но выходной поток catchError сохраняется (если catchError тоже не выдает ошибку).
Пример: Обработана ошибка API
actions$.pipe( filter(action =gt; action.type === 'fetchData'), mergeMap(() =gt; fetchData().pipe( map(data =gt; ({ type: 'dataFetchSuccess', data }) catchError(error =gt; of('dataFetchError')) )) )
Примечание: При fetchData
сбое поток actions$ не завершается сбоем и может обработать следующее значение и снова извлечь данные.
Оператор tap
предназначен для использования при побочных эффектах, он не влияет на поток. Другими словами, это никоим образом не меняет поток.
Пример: Оператор tap
может выполнять побочный эффект для всех случаев: next
, error
и complete
.
actions$.pipe( tap(console.log, console.error, () =gt; console.log('complete')), // or tap({ next: console.log, error: console.error, complete: console.log('complete'), }), )
Обработчик ошибок in subscribe
вызывается, если поток свернулся из-за ошибки. (Примечание: Практически catchError
оператор подписывается на входной поток с обработчиком ошибок, наблюдает и обрабатывает ошибку.)
Вывод: Для простого потока, который может быть свернут из-за ошибки, мы можем subscribe
обратиться к потоку с обработчиком ошибок.
Используйте catchError
для сложного потока, который не может быть полностью свернут.