请忽略变量名称和格式,因为我刚刚更改了它们.

我一直在try 为一个可观察对象实现RxJS错误处理,该对象执行一个操作(用户单击),然后从我们的表单发送请求对象,并将其传递给一个HTTP调用,如下所示.

问题:如果我在我们的网页上发送了一个后端不存在的请求(来自表单),它会失败,并得到一个错误(太棒了!),但如果我try 在try 失败后重新提交正确的请求,应用程序就会挂起并加载,并且不会做任何事情.

serivce.ts行文件

sendRequest$ = this.exampleRatingSubjectAction$.pipe(switchMap(exampleRequest => this.http.post<exampleresponse>(this.PCFUrl + '/example',exampleRequest).pipe(
  catchError(this.handleError)
 )),
 tap(data => console.log(data)),
 );

sendExampleRequestEconomy$ = this.exampleSubjectActionEconomy$.pipe(switchMap(exampleRequest=>  this.http.post<exampleresponse>(this.PCFUrl + '/example',exampleRequest)
 .pipe(
  catchError(this.handleError)
 )),
 tap(data => console.log(data)),
 );

private handleError(err: HttpErrorResponse): Observable<never> {
// in a real world app, we may send the server to some remote logging infrastructure
//instead of just logging it to the console
let errorMessage: string;
if (err.error instanceof ErrorEvent) {
// A client-side or network error occured. Handle it accordingly
errorMessage = `An error occured: ${err.error.message}`;
} else {
// The backend returned an unsuccessful response code.
// the resposne body may contain clues as to what went wrong,
errorMessage = `Backend returned code ${err.status}: ${err.message}`;
}
console.error(err);
return throwError(errorMessage);
}

component code:

exampleResponsePriority$ = this.dataService.sendExampleRequest$
.pipe(
   map(data => this.exampleResponsePriority = data),
   tap(data => { 
    this.showPageLoader = false; 
    this.calculatorService.checkMinOrDeficitRate(data);
}),
catchError( err => {
   this.showPageLoader = false;
   // await this.presentAlert(err);
   this.errorMessageSubject.next(err);
   console.log("priority")
   return EMPTY;
}));

exampleResponseEconomy$ = this.dataService.sendExampleRequestEconomy$
.pipe(
  map(data => this.exampleResponseEconomy = data),
  catchError( err => {
    this.showPageLoader = false;
    // await this.presentAlert(err);
    this.errorMessageSubject.next(err);
    console.log("economy")
   return EMPTY;
}));

我唯一的猜测是,我们的操作流已经在第一次单击时使用请求对象进行了更新,那么当来自后端的响应是500时,它可能会被困在上面,不允许重新提交?

我曾try 在失败的请求上更新操作流,但无法使其工作.

我觉得我只需要几行代码就可以了!

任何帮助都是最好的.

推荐答案

问题

看起来,在最后的catchError(在组件代码中),您将返回EMPTY RxJS流作为错误响应.根据RxJS的catchError年文档:

该运算符处理错误,但会将所有其他事件转发到结果可观测对象.如果源观察值以错误终止,则它将为map that error to a new observable, subscribe to it, and forward all of its events to the resulting observable.

link to documentation,重点补充道.

您的源观察器已因错误而终止,因此它不会在管道中运行前面的任何步骤.接下来的订阅将侦听EMPTY(doc link),这意味着永远不会调用订阅处理程序(也不会终止订阅).

备择

您可能希望try 返回源可观测对象,它将作为处理程序的第二个参数传递给catchError.例如,您的代码可能变为:

exampleResponsePriority$ = this.dataService.sendExampleRequest$
.pipe(
   map(data => this.exampleResponsePriority = data),
   tap(data => { 
    this.showPageLoader = false; 
    this.calculatorService.checkMinOrDeficitRate(data);
}),
catchError((err, caught) => {
   this.showPageLoader = false;
   // await this.presentAlert(err);
   this.errorMessageSubject.next(err);
   console.log("priority")
   return caught;
}));

此外,您可能希望研究一下docs for the retry operator,它可以用来代替(或与)catchError一起使用,以达到类似的结果.

Typescript相关问答推荐

如何根据数据类型动态注入组件?

从接口创建类型安全的嵌套 struct

动态判断TypScript对象是否具有不带自定义类型保护的键

使用带有RxJS主题的服务在Angular中的组件之间传递数据

SortKey类型不起作用,尽管它使用的单个类型工作正常<>'

webpack错误:模块找不到.当使用我的其他库时,

来自类型脚本中可选对象的关联联合类型

如何使所有可选字段在打印脚本中都是必填字段,但不能多或少?

在排版修饰器中推断方法响应类型

在列表的指令中使用intersectionObservable隐藏按钮

为什么我的导航在使用Typescript的React Native中不起作用?

有没有办法在Zod中使用跨字段验证来判断其他字段,然后呈现条件

如何从一个泛型类型推断多个类型

Typescript .根据枚举输入参数返回不同的对象类型

两个名称不同的相同打字界面-如何使其干燥/避免重复?

使用RXJS获取数据的3种不同REST API

如何使用angular15取消选中位于其他组件中的复选框

来自枚举的<;复选框和组件列表

断言同级为true或抛出错误的Typescript函数

是否可以使用元组中对象的键来映射类型