【问题标题】:async-await in canactivate() in Angular 7Angular 7 中的 canactivate() 中的异步等待
【发布时间】:2020-11-09 02:53:19
【问题描述】:

我正在编写一个代码来检查浏览器是否有 userInfo。如果没有,浏览器会调用 API 从服务器获取 userInfo。仅当存在有效的 userInfo 时,才允许用户导航到页面。

我的问题是 canactivate() 不等待调用完成。我试过其他线程中提到的解析器,但它也没有用。

所以,我设置了 async-await,但它也不起作用。 canactivate() 在 getUser() 完成之前返回。下面代码中的 async-await 的语法有错吗?

@Injectable()
export class AuthGuard implements CanActivate {

  constructor(private router: Router, private refService: RefService, private userInfoService: UserInfoService) {
  }

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {

    this.getUser();
    console.info('canActivate completed');
    return this.userInfoService.getUserInfo() !== null;
  }

  async getUser() {
    if(!this.userInfoService.getUserInfo()) {
      await this.refService.getTamUser().toPromise( ).then(data => {
        this.userInfoService.setUserInfo(data);
      });
    }
  }
}

【问题讨论】:

标签: angular typescript


【解决方案1】:

您可以将您的异步逻辑包装在 canActivate 函数本身作为 promise,这样 can canActivate 只会在 thencatch 块的承诺返回。 一定要作为一个 observable 返回。

 @Injectable()
export class AuthGuard implements CanActivate {

  constructor(private router: Router, private refService: RefService, private userInfoService: UserInfoService) {
  }

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
  if (!this.userInfoService.getUserInfo()) {
    this.refService.getTamUser().toPromise()
    .then(data => {
      if (data) {
        this.userInfoService.setUserInfo(data);
        console.info('canActivate completed');
        return of(true);
      } else {
        return false
      }
    })
    .catch(() => {
      return false;
    })
  } else {
    return of(this.userInfoService.getUserInfo() !== null);
  }
}

【讨论】:

    【解决方案2】:

    can Activate 不是 (a) 等待 getUser。我会这样做:

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
        const userInfo = this.userInfoService.getUserInfo()
        if (userInfo) {
          return userInfo !== null;
        } else {
          return this.refService.getTamUser().pipe(switchMap((data: any) => {
            this.userInfoService.setUserInfo(data);
            return of(data !== null);
          })) 
        }
      }
    

    首先检查用户信息是否存在。如果没有,则从 ref 服务获取用户信息并返回一个新的 boolean 类型的 observable。 false boolean 表示不允许访问或 refService 调用失败。

    阅读更多关于 switchMap here。简而言之:从原始 observable 的数据中创建一个新的 observable。

    【讨论】:

      猜你喜欢
      • 2019-09-29
      • 1970-01-01
      • 1970-01-01
      • 2018-02-08
      • 2017-06-10
      • 2021-10-22
      • 1970-01-01
      • 2014-06-06
      • 2017-09-14
      相关资源
      最近更新 更多