处理 RxJS 错误的正确方法是什么?

Ste*_*fan 6 error-handling rxjs typescript angular

RxJS 提供了很多处理错误的方法,但我很难理解每种方法以及它们的使用位置。我对 RxJS 了解得越多,对它的理解就越少。

如果我使用管道,就会出现 catchError。

如果我在管道内使用 Tap,则会有可选的错误参数。

如果我使用订阅,还有可选的错误参数。

我想在哪里使用一个错误处理程序而不是另一个?可选错误参数的用例有哪些?如果我使用tap的error参数,我还需要使用catchError吗?如果我有 catchError,我还需要使用 subscribes error 参数吗?

我想更好地了解每个错误处理程序,以及进行错误处理的正确方法是什么。

小智 7

RxJS 流的设计方式是错误导致整个流崩溃。为了防止这种行为,RxJS 提供了一个catchError运算符。它只是捕获一个错误;catchError 的输入流崩溃,但 catchError 的输出流被保留(如果 catchError 也没有抛出错误)。

示例:处理 API 错误

actions$.pipe(
  filter(action => action.type === 'fetchData'),
  mergeMap(() => fetchData().pipe(
    map(data => ({ type: 'dataFetchSuccess', data })  
    catchError(error => of('dataFetchError'))
  ))
)
Run Code Online (Sandbox Code Playgroud)

注意:当fetchData失败时,actions$ 流不会失败,并且能够处理下一个值并再次获取数据。


Operatortap旨在用于副作用,它对流没有影响。换句话说,它不会以任何方式改变流。

示例:操作员tap能够对所有情况执行副作用:next、error和complete。

actions$.pipe(
  tap(console.log, console.error, () => console.log('complete')),
  // or
  tap({
    next: console.log,
    error: console.error,
    complete: console.log('complete'),
  }),
)
Run Code Online (Sandbox Code Playgroud)

subscribe如果流由于错误而崩溃,则调用错误处理程序。(注意:实际上,catchError操作员使用错误处理程序订阅输入流,监视并处理错误。)


结论:对于可能因错误而崩溃的简单流,我们可以subscribe使用错误处理程序对流进行处理。

用于catchError无法完全折叠的复杂流。


Fat*_*med 5

使用订阅错误回调处理错误可以完成您的工作,但如果您想在发生错误时发出替代值,它会受到限制。(重置值)

例如,假设您正在等待您的可观察对象发出用户列表,但您希望在发生错误时获得一个空数组,您不能在订阅调用内的错误回调中执行此操作,但您可以使用捕获错误

getUsers$.pipe(
  catchError(error => of([]))
)
Run Code Online (Sandbox Code Playgroud)

您使用多个 catchError 运算符引发错误并添加替换值

 getUsers$.pipe(
   catchError(error => {
     return throwError(error);
   }),
   catchError(error => {
     return of([]);
   })
  ).subscribe(
    users=> console.log('users', users),
    err => console.log('Error', err),
  )
    
Run Code Online (Sandbox Code Playgroud)

在这种情况下,抛出的错误将永远不会到达订阅处理程序函数,您将在控制台日志中看到它

users []
Run Code Online (Sandbox Code Playgroud)