我在Angular中使用过rxjs,并且我熟悉在pipe
流中使用catchError
运算符,尤其是对于HttpClient(XHR(调用
我的问题是catchError
操作是如何工作的?它是如何在引擎盖下捕捉错误的?
https://www.learnrxjs.io/operators/error_handling/catch.html
import { throwError, of } from 'rxjs';
import { catchError } from 'rxjs/operators';
//emit error
const source = throwError('This is an error!');
//gracefully handle error, returning observable with error message
const example = source.pipe(catchError(val => of(`I caught: ${val}`)));
//output: 'I caught: This is an error'
const subscribe = example.subscribe(val => console.log(val));
更新:
使用Accepted Answer中的详细信息,我在StackBlitz TypeScript项目中用以下内容进行了测试。查看正在使用的try/catch和subscriber.error的好例子:
import { throwError, of, Observable } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
const exampleOne$ = new Observable(subscriber => {
throw new Error('thrown');
});
exampleOne$.pipe(
catchError(val => of(`Exmaple One ${val}`))
).subscribe(console.log); // Exmaple One Error: thrown
const exampleTwo$ = new Observable(subscriber => {
try {
throw new Error('native error')
}
catch (e) {
subscriber.error(e);
}
});
exampleTwo$.pipe(
catchError(val => of(`Example Two ${val}`))
).subscribe(console.log); // Example Two Error: thrown
catchError
运算符不会像使用try
/catch
语句捕获异常那样直接捕获错误。
在内部,它订阅应用它的可观察源,并镜像源的next
和complete
通知——也就是说,这些通知在操作符中流动时保持不变。
但是,如果操作员收到error
通知,它会将错误传递给提供的回调,从而为操作员的调用者提供处理错误的机会。
error
通知可以在可观察的实现中通过调用用户的error
方法来实现,如下所示:
const source = new Observable<string>(subscriber => {
subscriber.error(new Error'Kaboom!'));
});
这里不抛出异常,也不需要try
/catch
。错误通过其error
方法传递给订阅者——catchError
操作员订阅源,因此它就是订阅者。
这就是问题中使用的throwError
函数的实现方式。
error
通知也可以通过抛出异常来实现,如以下所示:
const source = new Observable<string>(subscriber => {
throw new Error('Kaboom!');
});
这里,Observable.subscribe
的实现中的try
/catch
语句将捕获异常,并通过调用订阅者的error
方法将错误通知传递给订阅者。
捕获抛出的异常是Observable
和运算符实现的责任。
无论在哪里传递用户指定的函数,例如在map
之类的运算符中,对这些函数的调用都被封装在try
/catch
语句中,并且任何捕获的异常都会通过订阅者的error
方法作为error
通知传递给订阅者。