【问题标题】:BehaviorSubject always defaulting to false before programmatically being set在以编程方式设置之前,BehaviorSubject 始终默认为 false
【发布时间】:2019-08-04 11:31:55
【问题描述】:

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

除了应用程序恢复并且用户登录外,一切都按预期工作。即使用户已登录并且BehaviorSubject 设置为 true,它也会在再次检查令牌之前短暂设置为 false,然后将其设置回真。这会导致短暂导航到/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']);
  }
});

【问题讨论】:

  • 如果你不希望 BehaviorSubject 有一个默认的 false 值,你可以使用 ReplaySubject(1) 而不是在你明确调用 next() 之前它不会发出。
  • @martin false 表示用户已注销,应该是默认的。
  • 所以你希望它有一个默认值而不是同时有一个默认值

标签: angular typescript ionic-framework rxjs


【解决方案1】:

您可以通过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))

【讨论】:

  • 这似乎在我刚刚运行的快速测试中有效。
  • @JoeScotto 很好。我进行了一些编辑,以展示一种在您的情况下效果更好的替代方案。有条件地设置去抖时间可以节省您在发出true 时用作去抖时间的时间。对于我的示例中使用的去抖时间,这为 100 毫秒。
  • 是的,我使用了 50ms 的条件去抖动...似乎工作完美。谢谢!
猜你喜欢
  • 1970-01-01
  • 2015-02-20
  • 2019-04-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-18
  • 1970-01-01
相关资源
最近更新 更多