clearTimeout偶尔会失败

时间:2017-01-03 20:08:12

标签: javascript angular typescript

我正在尝试在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调用似乎工作正常。换句话说,创建一个新计时器会以某种方式导致旧计时器生存。我在这里缺少什么?

谢谢!

3 个答案:

答案 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函数中,看看是否有帮助。