Angular 11 switchmap 在捕获错误后不起作用

Muk*_*thi 4 rxjs angular11

我的角度应用程序中有两个下拉菜单。第二个是根据第一个下拉值填充的。我正在使用切换映射。只要没有错误就可以正常工作。一旦没有值填充第二个下拉列表并且出现错误,当我更改第一个下拉列表中的值时,不会发生后续调用。我在这里做错了什么吗?

这是我的代码:

private customListItems$ = this.auditFilterService.subjectType$     // this is first option value
  .pipe(
    takeUntil(this.destroy$),
    filter(x => x && x !== ''),
    switchMap((selectedSubjectType) => {
      const result = this.customListsService.getCustomListItemsByTypeName({
        typeName: selectedSubjectType,
        onlyActive: true
      } as CustomListItemsByLocationParams);
      return result;
    }),
    catchError(err => {
      console.log('error', err);
      return of(undefined);
    })
  );
Run Code Online (Sandbox Code Playgroud)

Oli*_*ssé 5

Mulkil Deepthi的答案是正确的,但我想解释为什么从内部可观察的内部捕获错误很重要switchMap(这也与其他运算符相关,例如mergeMap, concatMap)。

在 中RX,错误意味着 Observable因错误而终止,因此您不会从中收到更多元素。

这在以下内容中得到了很好的解释ReactiveX documentation

OnError
表示 Observable 已因指定的错误条件而终止,并且不会再发出任何其他项目

Observable 终止
当 Observable 确实发出 OnCompleted 或 OnError 通知时,Observable 可能会释放其资源并终止,并且其观察者不应尝试与它进一步通信。

catchError不会阻止源可观察值的订阅终止,它只是将错误映射到新的可观察值并订阅它。
错误发生后,您只会收到来自 的 observable 返回的通知catchError(不会再从源 observable 收到任何项目,因为订阅已终止)。

这是文档中的一个很好的示例:

of(1, 2, 3, 4, 5)
  .pipe(
    map(n => {
      if (n === 4) {
        throw 'four!';
      }
      return n;
    }),
    catchError(err => of('I', 'II', 'III', 'IV', 'V'))
  )
  .subscribe(x => console.log(x));
  // 1, 2, 3, I, II, III, IV, V
Run Code Online (Sandbox Code Playgroud)

5永远不会收到,因为在映射时抛出错误4
发出返回的可观察量并以错误终止处理它并订阅包含这些元素的新可观察量map(...)1 2 3four
catchErrorI II III IV V

回到你最初的例子:

this.observable$
  .pipe(
    switchMap(value => this.createObservable(name)),
    catchError(error => {
      console.log(error);
      return of(undefined);
    })
  )
  .subscribe(v => console.log(v));
Run Code Online (Sandbox Code Playgroud)

如果返回的 observable 发出switchMap错误,订阅将被视为已终止,因此您将不会收到更多元素。catchError将此错误映射到一个新的可观察量,该可观察量将产生undefined.

如果您想维持初始订阅,则返回的 observableswitchMap不得发出错误。

您必须捕获以下错误switchMap

this.observable$
  .pipe(
    switchMap(value => 
      this.createObservable(name).pipe(
        catchError(error => {
          console.log(error);
          return of(undefined);
        })
      )
    )
  )
  .subscribe(v => console.log(v));
Run Code Online (Sandbox Code Playgroud)

在此示例中,switchMap由于catchError. 请注意,如果您不想发出任何值,
也可以使用empty()代替。of(undefined)