Angular 9/rxjs: 如何处理switchMap内部抛出的错误?
Angular 9/rxjs: How to handle an error thrown inside switchMap?
我正在使用 Angular (9) powered Bootstrap (6.1.0) TypeAhead 并像这样定义其搜索功能:
search = (text$: Observable<string>) => {
return text$.pipe(
debounceTime(200),
distinctUntilChanged(),
// switchMap allows returning an observable rather than maps array
switchMap((searchText) => {
if (!searchText || searchText.trim().length == 0) {
// when the user erases the searchText
this.dealerRepUserID = 0;
this.dealerRepChanging.emit(this.dealerRepUserID);
return EMPTY;
}
else if (this.dealerID == this.hostOrganizationID) {
// get a list of host reps
return this.myService.getHostRepsAutoComplete(searchText, this.includeInactive);
} else {
// get a list of dealer reps
return this.myService.getDealerReps(this.dealerID, searchText);
}
})
);
}
该函数必须 return 一个 Observable。如何捕获 switchMap 中抛出的错误?
你试过catchError
import { catchError } from 'rxjs/operators';
return text$.pipe(
debounceTime(200),
distinctUntilChanged(),
// switchMap allows returning an observable rather than maps array
switchMap((searchText) => {
if (!searchText || searchText.trim().length == 0) {
// when the user erases the searchText
this.dealerRepUserID = 0;
this.dealerRepChanging.emit(this.dealerRepUserID);
return EMPTY;
}
else if (this.dealerID == this.hostOrganizationID) {
// get a list of host reps
return this.myService.getHostRepsAutoComplete(searchText, this.includeInactive).pipe(catchError(error => of());
} else {
// get a list of dealer reps
return this.myService.getDealerReps(this.dealerID, searchText).pipe(catchError(error => of());
}
})
);
这是我的应用效果
public loadDataPerformance$: Observable<Action> = createEffect(() => {
return this.actions$.pipe(
ofType(RiskProfileActions.loadDataPerformance),
withLatestFrom(
this.store$.select(fromRoot.getAnalyticsFilterSelectedOptions),
this.store$.pipe(select(fromFactoryPerformance.getFactoryId))
),
switchMap(([{ recordDate }, filters, factoryId]) =>
this.riskProfileApiService.getDataPerformanceData(filters, factoryId, recordDate).pipe(
map((riskDataPerformanceData: PerformanceDataModel) =>
RiskProfileActions.loadRiskScoreBreakdownPerformanceSuccess(riskDataPerformanceData)
),
catchError(error => of(RiskProfileActions.loadRiskScoreBreakdownPerformanceFail(error)))
)
)
);
});
switchMap
本身不会抛出任何错误,可能会做一些意想不到的事情是返回的观察值 this.myService.getHostRepsAutoComplete
和 this.myService.getDealerReps
。捕获错误的一个棘手时刻是,只要有 error
抛出错误的可观察对象就会被杀死。
例如
observable$.pipe(
switchMap(() => observable2$),
catchError(() => doSomethingFunction())
).subscribe()
observable$
一旦出现错误就会完成,这将完成您的搜索流,错误后您将不会再获得任何数据。
正如 Phat Tran Ky 在他的示例中所展示的那样,错误处理应该发生在 switchMap
运算符
中的新流中
observable$.pipe(
switchMap(() => observable2$.pipe(catchError(() => doSomethingFunction())),
)
).subscribe()
只要从内部抛出错误,这样做就会终止内部可观察对象 (observable2$),但不会终止外部可观察对象的外部订阅 observable$
为了在一处处理错误,您可以做的进一步改进可能是将内部可观察对象合并为一个,例如,类似
observable$.pipe(
switchMap(() => {
return merge(
observable1$.pipe(filter(() => ${your if else condition for case 1})),
observable2$.pipe(filter(() => ${your if else condition for case 2})),
observable3$.pipe(filter(() => ${your if else condition for case 3})),
).pipe(catchError((error) => yourErrorHandlerFunction(error)))
})),
)
).subscribe()
我正在使用 Angular (9) powered Bootstrap (6.1.0) TypeAhead 并像这样定义其搜索功能:
search = (text$: Observable<string>) => {
return text$.pipe(
debounceTime(200),
distinctUntilChanged(),
// switchMap allows returning an observable rather than maps array
switchMap((searchText) => {
if (!searchText || searchText.trim().length == 0) {
// when the user erases the searchText
this.dealerRepUserID = 0;
this.dealerRepChanging.emit(this.dealerRepUserID);
return EMPTY;
}
else if (this.dealerID == this.hostOrganizationID) {
// get a list of host reps
return this.myService.getHostRepsAutoComplete(searchText, this.includeInactive);
} else {
// get a list of dealer reps
return this.myService.getDealerReps(this.dealerID, searchText);
}
})
);
}
该函数必须 return 一个 Observable。如何捕获 switchMap 中抛出的错误?
你试过catchError
import { catchError } from 'rxjs/operators';
return text$.pipe(
debounceTime(200),
distinctUntilChanged(),
// switchMap allows returning an observable rather than maps array
switchMap((searchText) => {
if (!searchText || searchText.trim().length == 0) {
// when the user erases the searchText
this.dealerRepUserID = 0;
this.dealerRepChanging.emit(this.dealerRepUserID);
return EMPTY;
}
else if (this.dealerID == this.hostOrganizationID) {
// get a list of host reps
return this.myService.getHostRepsAutoComplete(searchText, this.includeInactive).pipe(catchError(error => of());
} else {
// get a list of dealer reps
return this.myService.getDealerReps(this.dealerID, searchText).pipe(catchError(error => of());
}
})
);
这是我的应用效果
public loadDataPerformance$: Observable<Action> = createEffect(() => {
return this.actions$.pipe(
ofType(RiskProfileActions.loadDataPerformance),
withLatestFrom(
this.store$.select(fromRoot.getAnalyticsFilterSelectedOptions),
this.store$.pipe(select(fromFactoryPerformance.getFactoryId))
),
switchMap(([{ recordDate }, filters, factoryId]) =>
this.riskProfileApiService.getDataPerformanceData(filters, factoryId, recordDate).pipe(
map((riskDataPerformanceData: PerformanceDataModel) =>
RiskProfileActions.loadRiskScoreBreakdownPerformanceSuccess(riskDataPerformanceData)
),
catchError(error => of(RiskProfileActions.loadRiskScoreBreakdownPerformanceFail(error)))
)
)
);
});
switchMap
本身不会抛出任何错误,可能会做一些意想不到的事情是返回的观察值 this.myService.getHostRepsAutoComplete
和 this.myService.getDealerReps
。捕获错误的一个棘手时刻是,只要有 error
抛出错误的可观察对象就会被杀死。
例如
observable$.pipe(
switchMap(() => observable2$),
catchError(() => doSomethingFunction())
).subscribe()
observable$
一旦出现错误就会完成,这将完成您的搜索流,错误后您将不会再获得任何数据。
正如 Phat Tran Ky 在他的示例中所展示的那样,错误处理应该发生在 switchMap
运算符
observable$.pipe(
switchMap(() => observable2$.pipe(catchError(() => doSomethingFunction())),
)
).subscribe()
只要从内部抛出错误,这样做就会终止内部可观察对象 (observable2$),但不会终止外部可观察对象的外部订阅 observable$
为了在一处处理错误,您可以做的进一步改进可能是将内部可观察对象合并为一个,例如,类似
observable$.pipe(
switchMap(() => {
return merge(
observable1$.pipe(filter(() => ${your if else condition for case 1})),
observable2$.pipe(filter(() => ${your if else condition for case 2})),
observable3$.pipe(filter(() => ${your if else condition for case 3})),
).pipe(catchError((error) => yourErrorHandlerFunction(error)))
})),
)
).subscribe()