BehaviorSubject всегда по умолчанию ложно перед программной установкой - PullRequest
0 голосов
/ 13 марта 2019

Я использую BehaviorSubject для аутентификации в своем приложении, когда для него установлено значение true, это означает, что пользователь вошел в систему с токеном и допустимым сроком действия, и приложение должно перенаправить их на домашнюю страницу панели инструментов.Если значение равно false, им следует предложить войти в систему.

Все работает как положено, кроме случаев, когда приложение возобновляет работу и пользователь входит в систему. Даже если пользователь вошел в систему и для 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 Ответ

1 голос
/ 13 марта 2019

Вы можете передать через debounceTime, чтобы установить период времени, для которого будет использоваться только последнее значение. Так как это изменение может произойти в тике, 100 мс, вероятно, слишком много в вашем случае. Рассмотрите возможность сокращения времени в соответствии с вашими потребностями:

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))
...