angular - 在两个流之间来回切换(Observables)
问题描述
我想要完成的是,根据 cookie 的存在跟踪用户的会话。如果会话超时,我会自动注销用户。为了实现这一点,我正在等待 cookie 首先出现,即等待用户进行有效的 API 调用。然后,我开始查询 cookie,直到它不再存在。下面的代码第一次对我有用。但是,在我订阅了第一个流之后,当用户在不重新加载浏览器的情况下启动新会话时,我无法恢复它。
代码:
private _setupSession(): void {
const waitForCookie = interval(1000)
.pipe(
tap(() => {
console.log('waiting');
}),
switchMap(() => of(this._cookieService.get(COOKIE_STRING))),
filter((val) => !!val),
take(1));
const queryCookie = interval(1000)
.pipe(
tap(() => {
console.log('querying');
}),
switchMap(() => of(this._cookieService.get(COOKIE_STRING))),
distinct());
waitForCookie.pipe(concatMap(() => queryCookie))
.subscribe(
(val) => {
if (!val) {
this._router.navigate([''], {queryParams: {sessionTimedOut: true}});
}
},
(err) => {
console.log(err);
});
}
观察:当用户在登录页面时,我每秒都可以看到“等待”日志。用户登录后,我开始每秒看到“查询”日志。一旦会话超时,用户将返回登录页面。此时,我仍然在控制台中看到“查询”日志。一旦用户再次登录,我想做的是切换回“等待”并切换到“查询”。
解决方案
如果我了解您的要求,那么这就是您想要做的:
观察this._cookieService.get()
方法中的 cookie,如果该值是null/empty/undefined
然后将用户路由到登录页面,并this._cookieService.get()
每隔 1 秒继续观察 on 的值。
如果我的理解是正确的,那么:
我认为你可以通过只使用这样的一个流来实现这一点:
const queryCookie = interval(1000)
.pipe(
switchMap(() => of(this._cookieService.get(COOKIE_STRING))),
//skipwhile will ensure to avoid timeout on starting of the page/app
skipWhile(cookie => !cookie)
);
queryCookie
.subscribe(
(val) => {
if (!val) {
this._router.navigate([''], {queryParams: {sessionTimedOut: true}});
}
},
(err) => {
console.log(err);
});
顺便说一句 - 我建议不要每 1 秒查询一次。我猜您的应用程序可能会以某种方式在 localStorage 中将 cookie 设置为 null/empty/undefined。如果是这样,那么您可以使用 Subject/BehaviorSubject 使您的代码更好一些,并且可以避免查询 1 秒。这只是一个观察,因为我不知道您的应用程序设计。
推荐阅读
- html - 将导航定位在具有重叠 div 的下标题边框上 (HTML/CSS)
- javascript - 覆盖子元素中的样式化组件父 div 属性
- python - 通过复选按钮选择和绘制列表(python、tkinter)
- r - r中时间序列数据中的小时间隔问题
- mysql - mysql IF 值 = 0 复制到
- c# - 从数据库中检索 inkcanvas 笔画并打印
- linux - 如何保护 Linux 服务器免受意外文件删除
- r - 根据来自其他两个数据帧的两个条件创建一个新数据帧
- lua - 如何从具有另一部分条件的索引中获取一个字段的最大值
- javascript - 如何在nodejs中从CSV文件列中读取数据