假设我有这些

myInterval=setInterval(funcA,50);

function funcA(){
  //Some code that takes longer than 50ms to run
}

setTimeout(function(){clearInterval(myInterval);},10000}

假设 funcA 总是需要超过 50 毫秒才能使它变得简单。自然,许多 funcA 运行会堆积并排队。 clearInterval 会删除那些排队的运行 还是只是 停止 排队新的运行?

我确实做了一个 fiddle 来测试它,结果是 clearInterval 停止了所有 future 的执行,即使是那些已经排队的。我只需要确认这种行为是一致的(跨浏览器/平台)。

var myInterval=setInterval(funcA,20);

setTimeout(function(){
  clearInterval(myInterval);

  console.log('Clearing interval at ' + Date.now());

},400);

var lastRunTimeStamp=0;

function funcA(){
  while(Date.now()<lastRunTimeStamp+25){}
  lastRunTimeStamp=Date.now();
  console.log('Run at ' + lastRunTimeStamp);
}



- 更新 -

本题的排队执行假设不正确,请检查 T.J.克劳德回答解释。

最佳答案


不,他们不会,因为重复计时器的工作方式。浏览器中的计时器行为(现在)由 WHAT-WG "HTML5" specification 指定。在回调完成后,将下一个任务作为前一个任务的一部分进行排队,而不是与它分开; details here 。所以一次只有一个未完成的任务(在它排队之后,在 JavaScript 引擎可以拿起它并处理它之前)。

不*,但没有必要。计时器系统排队的任务的第一步是查看计时器是否仍在事件计时器列表中;如果不是,请在调用回调之前使用 the task terminates。所以就好像 clearInterval 删除了任务(例如,你以前排队的回调没有运行),但不是因为 clearInterval 清除了它(相反,这是因为任务被检查)。
测试和证明行为很容易:只需安排一个计时器,然后忙碌等待超过其间隔时间,然后清除它:

var counter = 0;
var timer = setInterval(function() {
  ++counter;
  console.log("timer fired:", counter);
  if (counter == 1) {
    setTimeout(busyWaitAndClear, 0);
  }
}, 500); // Every 500ms
function busyWaitAndClear() { // Obviously never really do this
  var done = Date.now() + 1000;
  while (done > Date.now()) {
    // wait
  }
  clearInterval(timer);
  console.log("timer cleared");
}

请注意,计时器仅触发一次,并且不会触发第二次,即使在我们忙等待时,至少有一个触发它的任务已排队。

*(“否” - description of clearInterval 没有说明有关读取待处理任务列表和删除按间隔排队但尚未拾取的任务的任何内容。)

关于javascript - 将 clearInterval 停止排队的间隔执行,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47263656/

10-12 05:27