Angular 9/rxjs:如何处理switchMap中抛出的错误?

Angular 9/rxjs:如何处理switchMap中抛出的错误?,rxjs,angular9,switchmap,Rxjs,Angular9,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 t

我正在使用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);
        }
      })
    );
  }
函数必须返回一个可观察的值。如何捕获switchMap中抛出的错误?

您尝试过捕获错误吗

这是我的应用程序效果

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.gethostrepsautomplete和this.myService.getDealerReps。捕捉错误的一个棘手时刻是,每当出现错误时,抛出错误的可观察对象就会被杀死

比如说

可观测管道 switchMap=>observable2$, catchError=>doSomethingFunction 订阅 一旦出现错误,observable$将被完成,这将完成您的搜索流,并且在错误发生后您将不会获得更多数据

正如Phat Tran Ky在其示例中所示,错误的处理应该发生在switchMap操作符中的新流中

可观测管道 switchMap=>observable2$.pipecatchError=>doSomethingFunction, 订阅 通过这样做,无论何时从内部抛出错误,它都将杀死内部可观察到的2$,但不会杀死外部可观察到的外部订阅$

为了处理一个点上的错误,您可以做的另一个增强可能是将内部可观测值合并到一个点上,例如

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()

这取决于什么错误。您可以在整个块上使用try-catch,也可以使用catchError操作符捕获此.myService.get*调用发出的错误通知,具体取决于您要执行的操作。或者您也可以将catchError放在switchMap之后。
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)))
        )
      )
    );
  });

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()