首页 > 解决方案 > rxjs中多次调用的角度处理错误

问题描述

在这种特殊情况下,我不知道使用 rxjs 处理 html 错误的最佳方法:

组件.ts

private open() {
  this.openSubscription = this.openService
    .open(this.id)
    .subscribe(res => {
      if (res) {
        // do something with result
      } else {
        this.openInError = true;
      }
    });
}

开放服务.ts

open(id: number): Observable<OpenContext> {
  const openContextObservable = new Observable<OpenContext>(
  observer => {
  this.openApiService
    .first(id)
    .pipe(
      catchError(err => of(err))
    )
    .subscribe(res => {
      this.openApiService
        .second(res.param1)
        .pipe(
          map(result=> {
            // do something with the result
            observer.next(openContext);
            observer.complete();
          }),
          catchError(err => of(err))
        )
    })
})}

在 service-api 中,我只返回 this.http.post(...) 和一些参数作为 Observable

我想首先捕获错误并在组件的订阅中处理它(订阅(res => ...,err => ...))。实际上,如果'first'出错,它会调用'second',即使它需要'first'的结果,之后它不会返回错误,只是如果订阅中没有响应,我会处理。

执行此操作并拥有干净代码的最佳方法是什么?我用 throwError 进行了测试,......但我被阻止了......

所以组件中预期的代码将是:

private open() {
  this.openSubscription = this.openService
    .open(this.id)
    .subscribe(
    res => {
      if (res) {
        // do something with result
      }
    },
    err => {
      if (err) {
        this.openInError = true;
      }
    });
}

或与 .pipe 和 map 等价的东西。

标签: angularerror-handlingrxjs

解决方案


1.) 删除catchErrors 因为这将捕获错误并将错误流转换为非错误流。

2.) 使用switchMap而不是嵌套订阅。

开放服务.ts

import { switchMap } from 'rxjs/operators';
....
open(id: number): Observable<OpenContext> {
  // you can get rid of openContextObservable as well.
  return this.openApiService
    .first(id)
    .pipe(
      // switch to this observable from the first one
      switchMap(res => this.openApiService.second(res.param1)),
      map(result => {
        // do stuff and transformations here but make sure you return result for your subscriber.
        return result;
      })
    );
)}

零件

private open() {
  this.openSubscription = this.openService
    .open(this.id)
    .subscribe(
    res => {
      if (res) {
        // do something with result
      }
    },
    err => {
      if (err) {
        this.openInError = true;
      }
    });
}

推荐阅读