如何在一个可观察的 http 错误后保持可观察链继续运行
How to keep observable chain going after http error in one observable
我有一个可观察链。这是一段代码:
//get dynamic tree
flatMap(res => this.dynamicReportId !== null ? this.reportService.getDynamicTree(this.dynamicReportId) : of({})),
tap(res => this.dynamicTree = res),
//get dynamic report
flatMap((res) => this.dynamicReportId !== null ? this.reportService.getDynamicReport(this.dynamicReportId) : of({})),
然而,当我从第一个请求(获取动态树)中得到 500 API 错误时,链停止并且永远不会进入第二个 flatMap(动态报告)。
这是函数 this.reportService.getDynamicTree()
:
get(path: string, params: HttpParams = new HttpParams()): Observable<any> {
return this.http.get(`${environment.apiBaseUrl}${path}`, {headers: this.setHeaders(true), params: params}).pipe(
catchError(error => this.processError(path, error)),
map((res: Response) => res));
}
其中 this.processError
returns observableThrowError(res);
如果出现错误,我应该return怎么办才能继续上链?还是其他方面的原因?
首先 - 继续链条破坏了链条的整个概念。但是,我认为这个问题应该可以通过一些相当简单的链迭代器和处理 HttpClient 和服务抛出的错误来解决。
我用我的解决方案创建了一个 StackBlitz 示例:https://stackblitz.com/edit/chain。对于simplycity,链returns数据在{ result: any, error: any }[]
。当然,就管道操作员而言,您几乎可以做任何事情来调整结果。
理想情况下,observableChain
功能将是独立的,并根据需要处理空结果 - 在您的情况下 returning { result: any, error: any }[]
它将 return {}
错误响应并记录错误。
如果出现错误,Observable
完成,所以如果你想在错误发生后 return 一个新的 Observable
,你必须使用 catchError
运算符是这样的:
//get dynamic tree
flatMap(res => this.dynamicReportId !== null ? this.reportService.getDynamicTree(this.dynamicReportId) : of({})),
tap(res => this.dynamicTree = res),
catchError(() => of({})),
//get dynamic report
flatMap((res) => this.dynamicReportId !== null ? this.reportService.getDynamicReport(this.dynamicReportId) : of({})),
tap
运算符安全地不执行回调,只是在错误发生时转发错误,因此只有在成功的情况下才会分配 this.dynamicTree
。
如果你想在服务而不是组件中处理错误,你必须 return 除了 observableThrowError(res);
来自 processError
的其他东西(例如 of({})
) 但这将执行 tap
回调并分配 this.dynamicTree
这可能是不受欢迎的行为。
我有一个可观察链。这是一段代码:
//get dynamic tree
flatMap(res => this.dynamicReportId !== null ? this.reportService.getDynamicTree(this.dynamicReportId) : of({})),
tap(res => this.dynamicTree = res),
//get dynamic report
flatMap((res) => this.dynamicReportId !== null ? this.reportService.getDynamicReport(this.dynamicReportId) : of({})),
然而,当我从第一个请求(获取动态树)中得到 500 API 错误时,链停止并且永远不会进入第二个 flatMap(动态报告)。
这是函数 this.reportService.getDynamicTree()
:
get(path: string, params: HttpParams = new HttpParams()): Observable<any> {
return this.http.get(`${environment.apiBaseUrl}${path}`, {headers: this.setHeaders(true), params: params}).pipe(
catchError(error => this.processError(path, error)),
map((res: Response) => res));
}
其中 this.processError
returns observableThrowError(res);
如果出现错误,我应该return怎么办才能继续上链?还是其他方面的原因?
首先 - 继续链条破坏了链条的整个概念。但是,我认为这个问题应该可以通过一些相当简单的链迭代器和处理 HttpClient 和服务抛出的错误来解决。
我用我的解决方案创建了一个 StackBlitz 示例:https://stackblitz.com/edit/chain。对于simplycity,链returns数据在{ result: any, error: any }[]
。当然,就管道操作员而言,您几乎可以做任何事情来调整结果。
理想情况下,observableChain
功能将是独立的,并根据需要处理空结果 - 在您的情况下 returning { result: any, error: any }[]
它将 return {}
错误响应并记录错误。
如果出现错误,Observable
完成,所以如果你想在错误发生后 return 一个新的 Observable
,你必须使用 catchError
运算符是这样的:
//get dynamic tree
flatMap(res => this.dynamicReportId !== null ? this.reportService.getDynamicTree(this.dynamicReportId) : of({})),
tap(res => this.dynamicTree = res),
catchError(() => of({})),
//get dynamic report
flatMap((res) => this.dynamicReportId !== null ? this.reportService.getDynamicReport(this.dynamicReportId) : of({})),
tap
运算符安全地不执行回调,只是在错误发生时转发错误,因此只有在成功的情况下才会分配 this.dynamicTree
。
如果你想在服务而不是组件中处理错误,你必须 return 除了 observableThrowError(res);
来自 processError
的其他东西(例如 of({})
) 但这将执行 tap
回调并分配 this.dynamicTree
这可能是不受欢迎的行为。