Как правильно обрабатывать ошибки в RxJS?

#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 для сложного потока, который не может быть полностью свернут.