将 clearInterval 停止排队间隔执行

Will clearInterval stop queued interval execution

假设我有这些

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 停止了所有未来的执行,即使是那些已经排队的。我只需要确认此行为是一致的(跨 browsers/platforms)。

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。克劳德回答解释。

Naturally, many funcA runs will pile up and be queued.

不,他们不会,因为重复计时器的工作方式。浏览器中的计时器行为(现在)由 WHAT-WG "HTML5" specification. Queuing the next task is done as part of the previous task, after your callback has completed, not separately from it; details here 指定。所以一次只有一个未完成的任务(在排队后,在JavaScript引擎可以拾取它并处理它之前)。

Will clearInterval remove those queued runs or just stop queuing new ones?

否*,但不必如此。定时器系统排队任务的第一步是查看定时器是否仍在活动定时器列表中;如果不是,请 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 没有说明任何有关读取待处理任务列表和删除按间隔排队但尚未提取的任务的信息。)