在 RxJS 中处理错误的正确方法是什么?
What is the proper way to handle errors in RxJS?
RxJS 提供了很多处理错误的方法,我很难理解每一种方法以及它们的用处。对RxJS越了解越不了解
如果我使用管道,就会出现 catchError。
如果我在管道内使用水龙头,则有可选的错误参数。
如果我使用订阅,还有可选的错误参数。
我想在什么地方使用一个错误处理程序而不是另一个?可选错误参数的用例是什么?如果我使用的是 tap 的错误参数,我还需要使用 catchError 吗?如果我有 catchError,我还需要使用订阅错误参数吗?
我想更好地了解每个错误处理程序,以及错误处理的正确方法是什么。
使用订阅错误回调处理错误可以完成你的工作,但如果你想在发生错误时发出替代值,它有限制。 (重置值)
例如,假设您正在等待您的可观察对象发出用户列表,但您希望在出现错误时获得一个空数组,您不能在订阅调用中的错误回调中这样做,但是你可以使用 catchError
getUsers$.pipe(
catchError(error => of([]))
)
您使用多个 catchError 运算符抛出错误并添加替换值
getUsers$.pipe(
catchError(error => {
return throwError(error);
}),
catchError(error => {
return of([]);
})
).subscribe(
users=> console.log('users', users),
err => console.log('Error', err),
)
在这种情况下,抛出的错误永远不会到达订阅处理程序函数,您将在控制台日志中看到它
users []
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'))
))
)
注意:当 fetchData
失败时,actions$ 流不会失败并且能够处理下一个值并再次获取数据。
Operator tap
设计用于副作用,它对流没有影响。换句话说,它不会以任何方式改变流。
示例:运算符 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'),
}),
)
如果流由于错误而崩溃,将调用 subscribe
中的错误处理程序。 (注意:实际上 catchError
运算符使用错误处理程序订阅输入流,观察并处理错误。)
结论:
对于可能因错误而折叠的简单流,我们可以 subscribe
到带有错误处理程序的流。
对无法完全折叠的复杂流使用catchError
。
RxJS 提供了很多处理错误的方法,我很难理解每一种方法以及它们的用处。对RxJS越了解越不了解
如果我使用管道,就会出现 catchError。
如果我在管道内使用水龙头,则有可选的错误参数。
如果我使用订阅,还有可选的错误参数。
我想在什么地方使用一个错误处理程序而不是另一个?可选错误参数的用例是什么?如果我使用的是 tap 的错误参数,我还需要使用 catchError 吗?如果我有 catchError,我还需要使用订阅错误参数吗?
我想更好地了解每个错误处理程序,以及错误处理的正确方法是什么。
使用订阅错误回调处理错误可以完成你的工作,但如果你想在发生错误时发出替代值,它有限制。 (重置值)
例如,假设您正在等待您的可观察对象发出用户列表,但您希望在出现错误时获得一个空数组,您不能在订阅调用中的错误回调中这样做,但是你可以使用 catchError
getUsers$.pipe(
catchError(error => of([]))
)
您使用多个 catchError 运算符抛出错误并添加替换值
getUsers$.pipe(
catchError(error => {
return throwError(error);
}),
catchError(error => {
return of([]);
})
).subscribe(
users=> console.log('users', users),
err => console.log('Error', err),
)
在这种情况下,抛出的错误永远不会到达订阅处理程序函数,您将在控制台日志中看到它
users []
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'))
))
)
注意:当 fetchData
失败时,actions$ 流不会失败并且能够处理下一个值并再次获取数据。
Operator tap
设计用于副作用,它对流没有影响。换句话说,它不会以任何方式改变流。
示例:运算符 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'),
}),
)
如果流由于错误而崩溃,将调用 subscribe
中的错误处理程序。 (注意:实际上 catchError
运算符使用错误处理程序订阅输入流,观察并处理错误。)
结论:
对于可能因错误而折叠的简单流,我们可以 subscribe
到带有错误处理程序的流。
对无法完全折叠的复杂流使用catchError
。