我正在尝试在Angular 2环境中管理计时器,而clearTimeout似乎只能在大约一半的时间内正常工作。我在用TypeScript写作。
我将计时器保留在自己的服务中:
export class TimeoutService {
constructor(
private router: Router,
private httpService: HttpService
) {}
//Properties
private timer;
//Methods
public clearTimer() {
clearTimeout(this.timer);
}
private logOut() {
return this.httpService.Post('api/session/logout', '');
}
private redirectToTimeoutPage() {
this.router.navigate(['/timeout']);
}
public refreshTimer() {
console.log('refreshing timer');
if (this.timer) {
this.clearTimer();
this.setTimer();
}
}
public startTimer() {
this.setTimer();
}
private setTimer() {
this.timer = setTimeout(() => {
this.logOut()
.then(() => {
this.clearTimer();
this.redirectToTimeoutPage();
});
}, 30000);
}
}
我从refreshTimer方法的console.log中知道,当我期望它时,它会被调用,而不是其他。但是,大多数情况下,clearTimeout调用不会取消较早的计时器,并且即使它们应该被新的计时器替换,它们也会在30秒后启动。
我经历过其他有关此事的SO问题,并且根据我的情况,没有一个适用于我的情况。
我得到的一条线索,我无法破译,如果我在refreshTimer中删除对this.setTimer()
的调用,那么clearTimeout调用似乎工作正常。换句话说,创建一个新计时器会以某种方式导致旧计时器生存。我在这里缺少什么?
谢谢!
答案 0 :(得分:5)
在refreshTimer
中,您需要在致电this.clearTimer()
之前致电this.setTimer()
。
但是,在startTimer
中,您不会致电this.clearTimer()
。因此,如果调用代码多次调用startTimer
而没有执行任何调用this.clearTimer
之间的任何内容,那么您将开始多次超时,但只有最后一个将被您的类记住
this.clearTimer
时取消。
答案 1 :(得分:2)
在clearTimeout
功能中,您不仅要清除计时器,还要重置timer
变量:
public clearTimer() {
clearTimeout(this.timer);
this.timer = null; // <-- You also want your variable to become null here.
}
然后,在调用clearTimer()
之后运行的任何代码都会正确地将timer
变量评估为null
,这正确地指示没有计时器存在。简单地停止运行计时器对于您的包装器来说是不够的。
另外(FYI),正如我在评论中所说,初始化所有变量是一个非常好的最佳实践,因此没有“惊喜”值出现在任何地方。
private timer;
应该是:
private timer = null;
答案 2 :(得分:1)
我会将调用clearTimer
移到setTimer
函数中,看看是否有帮助。