typescript 在Angular/RxJS中尝试失败后,如何重新提交可观察到的动作流?

wbgh16ku  于 2023-05-01  发布在  TypeScript
关注(0)|答案(1)|浏览(134)

请忽略变量名和格式,因为我刚刚更改了它们。
我一直在尝试实现RxJS的错误处理,它采取一个动作(用户点击),然后从我们的表单发送请求对象,并将其传递给HTTP调用,如下所示。
问题:如果我在我们的网页上发送一个请求(从一个表单),而这个请求在后端不存在,它会失败,我会得到一个错误(太好了!),但是如果我尝试在失败后重新提交一个正确的请求,应用程序只是挂起和加载,不做任何事情。
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时,它可能会卡在上面,不允许重新提交?
我尝试过在失败的请求上更新动作流,但无法使其工作。
我觉得我只差几行代码了!
任何帮助将是伟大的。

zlhcx6iw

zlhcx6iw1#

问题

看起来,在最终的catchError(在组件代码中)中,您返回EMPTY RxJS流作为错误响应。根据catchError的RxJS文档:
该操作符处理错误,但沿着其他事件转发到结果observable。如果源observable因错误而终止,它将将该错误Map到新的observable,订阅它,并将其所有事件转发到结果observable
link to documentation,重点已添加。
您的源代码观察器已经终止并出现错误,因此它不会运行管道中的任何早期步骤。订阅将侦听EMPTYdoc link),这意味着订阅处理程序将永远不会被调用(订阅也不会终止)。

备选

您可能希望尝试返回源可观察对象,它作为处理程序的第二个参数传递给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(或与catchError结合使用)来实现类似的结果。

相关问题