在我 "reset" 之后 setTimeout 是否有触发两次的风险?
Is there a risk that setTimeout will fire twice after I "reset" it?
有时我会使用以下概念:
class ResetableTimeout extends EventEmitter {
constructor() {
this.id = -1;
}
start(delay) {
clearTimeout(this.id);
this.id = setTimeout(() =>{this.emit("done");}, delay);
}
}
例如,这样的架构可用于节流操作。
现在我注意到在这些情况下这可能会触发两次:
setTimeout
开始超时
start(delay)
被调用并正在执行
- 超时触发,回调被推送到事件循环中,等待
start(delay)
结束
clearTimeout
被调用,但超时已经完成
start(delay)
结束并执行超时回调
delay
毫秒后,timeout 的回调再次执行
这可能吗?如果可能如何预防?如果不可能,是什么阻止了它的发生?
不,这是不可能的。如果内部超时已经触发,clearTimeout
将从事件队列中删除超时。它确保在您调用 clearTimeout
.
后回调不会 运行
In the spec,有一个活动计时器列表,定时事件循环任务从中获取要执行的回调,并且clearTimeout
清除该列表中的计时器,因此即使已经安排了任务,它仍会在执行回调之前检查计时器是否仍处于活动状态。
有时我会使用以下概念:
class ResetableTimeout extends EventEmitter {
constructor() {
this.id = -1;
}
start(delay) {
clearTimeout(this.id);
this.id = setTimeout(() =>{this.emit("done");}, delay);
}
}
例如,这样的架构可用于节流操作。
现在我注意到在这些情况下这可能会触发两次:
setTimeout
开始超时start(delay)
被调用并正在执行- 超时触发,回调被推送到事件循环中,等待
start(delay)
结束 clearTimeout
被调用,但超时已经完成start(delay)
结束并执行超时回调delay
毫秒后,timeout 的回调再次执行
这可能吗?如果可能如何预防?如果不可能,是什么阻止了它的发生?
不,这是不可能的。如果内部超时已经触发,clearTimeout
将从事件队列中删除超时。它确保在您调用 clearTimeout
.
In the spec,有一个活动计时器列表,定时事件循环任务从中获取要执行的回调,并且clearTimeout
清除该列表中的计时器,因此即使已经安排了任务,它仍会在执行回调之前检查计时器是否仍处于活动状态。