我想使用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']);
});
}
我希望当我们第一次启动该应用程序且没有用户时,间隔不会运行。工作正常!
我希望登录后会发送一个新的非null sessionUser事件,我们开始间隔直到isAuthenticated(检查会话是否到期)为false,然后仅使用1个事件注销。工作正常!
我希望,如果我手动注销,将发送一个新的null sessionUser事件,该事件将停止间隔。这是行不通的,因为它仍然要经过一次isAuthenticated并再次调用一次才能删除。不理想,但我可以解决。更大的问题是,当我再次登录时,间隔仅运行4次(为什么?),然后停止运行并检查isAuthenticated。
知道为什么会这样吗?您是否建议另一种方法?
答案 0 :(得分:2)
我不确定您想要的逻辑,但是似乎您可以重新构建已经拥有的链。然后,如果您希望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(...);