在以编程方式设置之前,BehaviorSubject始终默认为false

时间:2019-03-13 17:21:07

标签: angular typescript ionic-framework rxjs

我在我的应用程序中使用BehaviorSubject进行身份验证,如果将其设置为true,则意味着用户已使用令牌和有效到期时间登录,并且应用程序应将其重定向到主仪表板页面。如果为假,则应提示他们登录。

一切正常,但应用恢复运行且用户登录后,一切正常。即使用户已登录且BehaviorSubject设置为true,在再次检查令牌之前,它也会短暂地设置为false。然后将其设置回true。这样可以简短导航到/intro,然后立即正确导航/users/dashboard

有没有办法防止这种故障导航?

authentication.service.ts

export class AuthenticationService {
  state = new BehaviorSubject(false);

  constructor(
    private storage: Storage,
    private platform: Platform
  ) {
    this.platform.ready().then(() => {
      this.checkToken();
    });
  }

  /**
   * Ensures the user has access and is not passed their expiration
   */
  checkToken() {
    this.storage.get('token').then(token => {
      if (token) {
        this.storage.get('expiration').then(expiration => {
          const currentDate = moment.utc().format('YYYY-MM-DD HH:mm:ss');
          if (moment(currentDate).isBefore(expiration)) {
            this.state.next(true);
          }
        });
      }
    });
  }
}

app.component.ts

// Authentication
this.auth.state.subscribe(state => {
  alert(state);
  if (state) {
    this.menuCtrl.enable(true);
    this.router.navigate(['users', 'dashboard']);
  } else {
    this.menuCtrl.enable(false);
    this.router.navigate(['intro']);
  }
});

1 个答案:

答案 0 :(得分:1)

您可以通过debounceTime来设置一个时间范围,在该时间范围内将仅发射最新值。由于这种变化可能会在瞬间发生,因此在您的情况下100ms可能太多了。考虑根据您的需要减少时间:

this.auth.state.pipe(debounceTime(100)).subscribe(state => {
  alert(state);
  if (state) {
    this.menuCtrl.enable(true);
    this.router.navigate(['users', 'dashboard']);
  } else {
    this.menuCtrl.enable(false);
    this.router.navigate(['intro']);
  }
});

可以说在反跳上节省一些时间的解决方案是使用仅对false值起作用的条件反跳:

debounce(state => timer(state ? 0 : 100))