javascript - 为什么switchMap中的间隔停止发射值
问题描述
我想使用 rxjs 在我的应用程序中轮询用户会话,但仅在用户会话处于活动状态时。
我将用户会话存储在会话存储中。当我们打开应用程序时,它是空的,当我们登录时它会被刷新,并且它所附加的 BehaviourSubject 也会被更新。然后我开始一个 rxjs 间隔,直到会话过期,这样我就可以调用注销。
sessionUser$ = new BehaviorSubject<UserAuthSession>(this.getSessionUser());
private pollSessionTimeout(): void {
this.sessionUser$
.pipe(
filter(user => {
return user !== null;
}),
switchMap(() => interval(1000)),
skipWhile(this.isAuthenticated),
take(1)
)
.subscribe(x => {
console.log('Poll is deleting session', x);
this.deleteSession();
this.router.navigate(['auth/login']);
});
}
我希望当我们第一次启动应用程序并且没有用户时,间隔不会运行。这是有效的!
我希望在我们登录后,发送一个新的非空 sessionUser 事件,我们开始间隔,直到 isAuthenticated (检查会话是否过期)为假,然后只使用 1 个事件注销。这是有效的!
我希望如果我手动注销,则会发送一个新的空 sessionUser 事件来停止间隔。这不起作用,因为它仍然通过一次 isAuthenticated 并再次调用 delete 。不理想,但我可以解决它。更大的问题是当我再次登录时,间隔只运行 4 次(为什么?)然后停止运行并检查是否 isAuthenticated。
知道为什么会这样吗?你建议另一种方法吗?
解决方案
我不完全确定你想要的逻辑,但似乎你可以重组你已经拥有的链。然后,如果你想interval
停止发射,你可以EMPTY
从switchMap
.
import { EMPTY } from 'rxjs';
...
this.sessionUser$
.pipe(
switchMap(user => {
if (user) {
return interval(1000).pipe(
skipWhile(this.isAuthenticated),
take(1)
);
} else {
return EMPTY;
}
})
).subscribe(...);
推荐阅读
- javascript - 如何防止 Mouse4 单击向后导航?
- sql - 根据值从表中获取范围
- asp.net-core - 带有 ASP.NET Core 3.1 Razor 页面的 Microsoft 身份平台中的可疑错误
- c++ - 在 gcc windows api 字符串处理中启用 UNICODE
- reactjs - 不能在 React-Native 中使用导航和道具?
- php - 如何以 symfony 1.4 形式读取默认值?
- python - 保存的 .wav 文件没有数据
- python - 如何遍历时间范围?
- arrays - 如何在c中将文本拆分为二维数组
- angular - 子路由中定义的组件不运行 NgOnInit 生命周期函数