[英]How to control interval in rxjs? - inactivate timer in angular
我尝试在 angular 应用程序中实现一种“会话计时器”。 当(她)在指定时间内没有点击任何键时,它将注销用户。 一切正常,直到第一次注销。 第二次登录后,定时器的重置方法不起作用。 无论执行的操作如何,用户都会在指定时间后注销。
我在StackBlitz上做了一个演示
这是服务代码:
@Injectable({
providedIn: "root"
})
export class SessionTimerService {
private readonly sessionTimer: Observable<number> = interval(10000); // 10 sec
private sessionTimerController: Subject<void>;
public constructor(private readonly router: Router) {}
public initTimer(): void {
this.sessionTimerController = new Subject<void>();
this.sessionTimer
.pipe(
take(1),
takeUntil(this.sessionTimerController)
)
.subscribe(() => {
console.log("logout");
this.sessionTimerController.next();
this.sessionTimerController.complete();
this.router.navigate(["/login"]);
});
}
public resetTimer(): void {
if (this.sessionTimerController && !this.sessionTimerController.closed) {
console.log("reset");
this.sessionTimerController.next();
this.sessionTimerController.complete();
this.initTimer();
}
}
public stopTimer(): void {
if (this.sessionTimerController && !this.sessionTimerController.closed) {
console.log("stop");
this.sessionTimerController.next();
this.sessionTimerController.complete();
}
}
}
window.relaod()
不是这个问题的好答案。
问题是您在第二次登录时创建了两个独立的计时器,因为第一次登录时this.sessionTimerController === null
并且您检查此条件:
onMouseMove
里面。MainComponent
的构造函数中。 第二个问题是方法initTimer()
不检查是否已经有一个计时器:
因此,在创建新计时器之前,您可以完成前一个计时器,这样您就知道永远只有一个计时器:
private sessionTimerController: Subject<void> = new Subject<void>();
...
public initTimer(): void {
console.log('initTimer');
this.sessionTimerController.next();
this.sessionTimerController.complete();
this.sessionTimerController = new Subject<void>();
...
现场演示: https : //stackblitz.com/edit/angular-session-timer-yqdxco?file= src/app/ session-timer.service.ts
在我看来,在您的用例中,完全摆脱Subject
会更容易,因为它只会使事情变得复杂并使用单个Subscription
对象来取消任何以前的计时器。
RXJS 功能强大,您可以unsubscribe
正在进行的事件,因此我设法在此解决方案中做到了这一点
https://stackblitz.com/edit/angular-session-timer-jpkxnj
这是服务代码
@Injectable({
providedIn: "root"
})
export class SessionTimerService {
savedSub: Subscription;
public constructor(private readonly router: Router) {
}
public initTimer(): void {
this.savedSub = of(true).pipe(delay(5000))
.subscribe(() => {
this.router.navigate(['login']);
this.savedSub.unsubscribe();
})
}
public resetTimer(): void {
if(this.savedSub){
this.savedSub.unsubscribe();
this.savedSub = null;
this.initTimer();
}
}
onDestroy(){
if(this.savedSub){
this.savedSub.unsubscribe();
this.savedSub = null;
}
}
}
initTimer 将等待 5 秒。当没有任何事情可以阻止它时,它会在您unsubscriped
的订阅引用消失并且不会触发时注销。单击鼠标,我们将unsubscribe
并从头开始重新运行计时器。
但你需要取消或null
订阅的值,如果没有人停止计时器..那为什么我们做的onDestroy
从主组件调用时ngOnDestroy
工作
ngOnDestroy(){
this.sessionTimer.onDestroy();
}
希望能解决你的问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.