CanActivate ждать и брать из магазина - PullRequest
0 голосов
/ 06 апреля 2020

У меня есть следующий метод в моем классе, который реализует из CanActivate:

export class CanActivateLoginedInforamtion implements CanActivate {
  constructor(private store: Store<AppState>) {}

  canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<boolean>{
    return timer(10000).pipe(
      () => this.store.select(({ user: { loginState }}) => {          
        console.log(loginState); 
        return loginState === 'LOGINED' 
      })
    );
  }
}

Но мой store.select возвращается мгновенно и не ждет десять секунд, почему?

При использовании обещания:

export class CanActivateLoginedInforamtion implements CanActivate {
  constructor(private store: Store<AppState>) {}

  canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Promise<boolean>{
    return new Promise((resolve) => {
      this.store.select(({ user: { loginState }}) => { 
        console.log(loginState); resolve(loginState === 'LOGINED');
      })
    })
  }
}

1 Ответ

1 голос
/ 06 апреля 2020

Это наблюдаемый эквивалент вашего примера, основанного на обещании:

export class CanActivateLoginedInforamtion implements CanActivate {
  constructor(private store: Store<AppState>) {}

  canActivate(route: ActivatedRouteSnapshot, 
    state: RouterStateSnapshot
  ): Observable<boolean> {
    return this.isLoggedIn();
  }

  private isLoggedIn(): Observable<boolean> {
    return this.store.select(({ user: { loginState }}) => {          
      return loginState === 'LOGINED';
    });
  }
}

this.store.select() возвращает Observable<boolean>, так что вы можете просто вернуть его из canActivate. Я переместил запрос магазина в новую функцию, чтобы, как мы надеемся, сделать ее немного понятнее.

Если по какой-то причине вы хотите подождать 10 секунд перед вызовом, вы можете запросить свой магазин после timer с использованием switchMap в трубе. Это эквивалентно цепочкам обещаний.

Вам также нужно будет использовать take(1), чтобы ограничить количество событий таймера, которые вы хотите получать.

export class CanActivateLoginedInforamtion implements CanActivate {
  constructor(private store: Store<AppState>) {}

  canActivate(route: ActivatedRouteSnapshot, 
    state: RouterStateSnapshot
  ): Observable<boolean> {
    return timer(10000).pipe(
      take(1),
      switchMap(() => this.isLoggedIn())
    );
  }

  private isLoggedIn(): Observable<boolean> {
    return this.store.select(({ user: { loginState }}) => {          
      return loginState === 'LOGINED';
    });
  }
}
...