Angular:解决void返回函数内Promise的Sonar问题及catchError用法
RxJS问题处理:finalize返回Promise提示修复与catchError中Promise的正确用法
一、修复finalize中返回Promise的SonarCloud提示
你的代码中#2位置的finalize回调使用了async函数,而async函数默认会返回Promise,但RxJS的finalize要求回调必须返回void,这就是SonarCloud触发提示的原因。以下是两种可行的修复方案:
方案1:无需等待导航完成时,移除async/await
如果不需要等待导航完成再执行后续逻辑,直接调用router.navigate即可,不需要await:
finalize(() => { this.spinner.hide('spinner'); this.router.navigate([`admin/standard-profiles/`]); // 去掉async和await })
方案2:需要等待导航完成时,用IIFE包裹异步逻辑
如果必须等待导航完成(比如后续操作依赖导航后的路由状态),可以用立即执行异步函数表达式(IIFE)包裹逻辑,确保finalize的回调返回void:
finalize(() => { this.spinner.hide('spinner'); // 用IIFE包裹异步逻辑,回调本身返回void (async () => { await this.router.navigate([`admin/standard-profiles/`]); // 这里添加需要等待导航完成后执行的代码 })(); })
二、catchError中正确使用Promise方法
RxJS的catchError强制要求返回Observable,不能直接返回Promise。如果要在catchError中调用Promise类型的方法,必须用from操作符将Promise转换为Observable:
基础用法示例
假设你的handleError方法返回Promise,修改catchError部分如下:
catchError(() => { // 使用from将Promise转为Observable return from(this.handleError(`error_translation`, `Error`)).pipe( // 根据业务需求处理:比如返回默认值,或者返回空流 map(() => { // 返回符合当前流类型的默认值,若不需要返回值可使用empty() return null; }) ); })
处理Promise执行失败的情况
如果Promise本身可能执行失败,可以在内部嵌套catchError处理该错误:
catchError((originalError) => { return from(this.handleError(`error_translation`, `Error`)).pipe( catchError((promiseError) => { // 处理Promise执行失败的情况,返回新的错误Observable return throwError(() => new Error(`原请求错误:${originalError}, 错误处理Promise失败:${promiseError}`)); }) ); })
原始问题代码
private editPersonSubject = new Subject<FormData>(); private editPersonAction$ = this.editPersonSubject.asObservable() .pipe( switchMap((form: FormData) => { return this.personService.edit(form).pipe( tap(() => { this.notificationService.showMsgSuccess( `success_translation`, `OK updated person`); }), catchError(() => this.handleError( // #1 `error_translation`, `Error`)), finalize(async () => { this.spinner.hide('spinner'); await this.router.navigate([`admin/standard-profiles/`]); // #2 }) ); }), this.mapToPersonProfileFormVm() ); // merging Vm$ = merge( this.editPersonAction$$, ).pipe( scan((prevVm: StandardPersonProfile, mutationFn: (vm: StandardPersonProfile) => StandardPersonProfile) => mutationFn(prevVm), { Person: null } as StandardPersonProfile
内容的提问来源于stack exchange,提问作者ruddnisrus
相关产品推荐
相关产品推荐

