JavaScript 如何在 1 秒内准确执行代码 1000 次

How to execute code exactly 1000 times in 1 second in JavaScript

n = 0;
var timer = setInterval(function() {
    if (n == 0) {
        console.log(new Date());
    }
    // execute some other code here
    n++;
    if (n == 1000) {
        clearInterval(timer);
        console.log(new Date());
    }
}, 1);

此代码执行大约需要 3-4 秒,具体取决于机器和浏览器。如何让它在 1 秒内执行?

Javascript 浏览器中的计时器不准确(对于这种用法,C 会更好)。

但是,如果延迟尽可能高,您会获得更好的平均准确度,尤其是避免低值,例如 1 毫秒。

很难在一秒钟内对一个函数进行 1000 次均匀定时调用。一毫秒是一个低值,触发函数本身的简单执行(加上处理计时器的开销)可能需要接近 1 毫秒(或可能更多)的时间......这意味着 JS 解释器在 1 毫秒后调用该函数, 执行代码然后设置一个新的 1ms 计时器。因此调用之间的间隔超过 1 毫秒。

JS 解释器做类似的事情

At t   call function     <-- this takes
       execute function  <-- some 
at t+x set new 1ms timer <-- time
etc...

但是,如果您有能力在接近 1 秒的时间范围内结束该过程(比现在的 3-4 秒),请尽可能多地 1 毫秒电话,这是可能的。

var n = 0;

var timer= setInterval(function(){
          if(n++ == 0) {
                console.log(new Date());
          }
     }, 1);

setTimeout(function() {
         clearInterval(timer);
         console.log("Got n="+n+" at "+(new Date()));
     }, 1000);

这与您的程序基本相同

  • n每1ms递增
  • 然而进程的结束由另一个 1 秒计时器控制

在 Chrome 中,我得到 252 n 个增量并且两个日期相隔约 1 秒。

ECMA Script 6

中尝试相同的脚本

'use strict';

var n = 0;

var timer = setInterval(() => { 
    n++;
}, 1);
console.log( new Date() );

setTimeout(() => {
 clearInterval(timer);
 console.log("Final N Value: "+n+" at "+ (new Date()) );
}, 1000);

这里演示了每次迭代使用一个计时器的方法。执行 1000 "iterations" 个相同的回调大约需要 1 秒。设计比较粗糙,只是个例子。

jsFiddle Demo

//Function to compose the array of timers
function timers(count, callback){
  var timers = [];
  for(var i = 0; i < count; i++){
    timers.push(timer(callback,i));
  }
  return timers;
};
//Function to compose individual timer
function timer(callback, delay){
  return function(){
    setTimeout(callback,delay);
  };
};

//Usage
console.log("Start:",new Date()); //timestamp

var display = document.querySelector("#display");

var settings = { n : 0 };

display.innerHTML = settings.n;

//Arrange timers and callback
var set = timers(1000,function(){
    this.n++;
  display.innerHTML = this.n;
    if(this.n === 1000) console.log("End:",new Date());
}.bind(settings));

//Execute timers
for(var i = 0; i < set.length; i++){ set[i](); }
<div id="display">
</div>

所有浏览器对此的处理方式不同。在 大多数 浏览器中,尤其是 chrome,任务执行的默认最小可能时间量(如使用间隔或超时)是 4 毫秒。

4 毫秒 window 的结果是您的 1000 次迭代在大约 4 秒内完成。因此,显然这比 1000 次迭代中所需的 1 秒长。

在现代浏览器中执行时,没有一种理想的(可能的?)方法可以在 JavaScript 中完成 精确的 1 毫秒迭代。如果 space(内存和处理能力)不是问题,您最好的选择是为每次迭代手动创建一个计时器,然后执行整组计时器。这当然有其自身的问题,例如每个任务是否按预期执行。