Angular中如何对.subscribe使用await解决路由守卫鉴权异步问题
问题根因
你遇到的问题核心是两个用法错误:
await关键字只能等待Promise对象执行完成,而subscribe()方法调用后返回的是RxJS的Subscription订阅实例,不是Promise,因此await不会等待接口请求返回,代码会直接往下执行,导致返回的还是初始值false。- Angular的
CanActivate接口原生支持返回Observable<boolean>、Promise<boolean>、boolean三种类型,不需要你自己声明变量存状态、手动处理异步等待。
推荐解决方案(直接返回Observable,无需转Promise)
这是Angular官方推荐的写法,路由守卫会自动等待Observable emit结果后再判断是否放行:
import { map, catchError } from 'rxjs/operators'; import { of } from 'rxjs'; export class AuthGuard implements CanActivate { constructor (private auth: AuthService){} canActivate( route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> { return this.auth.getAuthStatus().pipe( // 接口请求成功时判断状态码 map(res => res.status === 200), // 接口报错、返回401/403等异常状态时,统一返回未认证 catchError(() => of(false)) ) } }
如果你确实需要用Promise的写法
可以用RxJS提供的firstValueFrom方法把Observable转为Promise,不要手动subscribe:
import { firstValueFrom } from 'rxjs'; export class AuthGuard implements CanActivate { constructor (private auth: AuthService){} async canActivate( route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean> { try { const res = await firstValueFrom(this.auth.getAuthStatus()); return res.status === 200; } catch (error) { // 接口异常场景返回未认证 return false; } } }
注意:如果你使用的是RxJS 6及更早版本,可以用toPromise()方法替代firstValueFrom,但该方法在RxJS 7中已被标记为废弃。
内容的提问来源于stack exchange,提问作者Kleecarim
相关产品推荐
相关产品推荐

