 闽公网安备 35020302035485号
                
                闽公网安备 35020302035485号
                setTimeout(callback, 进入主线程的时间)所以什么时候可以执行 callback,需要看 主线程前面还有多少任务待执行。由此,才有了这个问题。我们可以通过这个场景来进行演示:

functiontimer() { 
   var speed = 50, // 设定间隔 
   counter = 1,  // 计数 
   start = new Date().getTime(); 
    
   functioninstance() 
   { 
    var ideal = (counter * speed), 
    real = (new Date().getTime() - start); 
    // 堆代码 duidaima.com
    counter++; 
    form.ideal.value = ideal; // 记录理想值 
    form.real.value = real;   // 记录真实值 
    var diff = (real - ideal); 
    form.diff.value = diff;  // 差值 
    window.setTimeout(function() { instance(); }, speed); 
   }; 
   window.setTimeout(function() { instance(); }, speed); 
} 
timer(); 
而我们如果在 setTimeout 还未执行期间加入一些额外的代码逻辑,再来看看这个差值。... 
window.setTimeout(function() { instance(); }, speed); 
for(var x=1, i=0; i<10000000; i++) { x *= (i + 1); } 
} 
... 


// 模拟代码 
function setTimeout2 (cb, delay) { 
    let startTime = Date.now() 
    loop() 
   
    functionloop () { 
      const now = Date.now() 
      if (now - startTime >= delay) { 
        cb(); 
        return; 
      } 
      requestAnimationFrame(loop) 
    } 
} 


... 
 window.setInterval2(function () { instance(); }, speed); 
} 
for (var x = 1, i = 0; i < 10000000; i++) { x *= (i + 1); } 
... 


function timer(time) { 
    const startTime = Date.now(); 
    while(true) { 
        const now = Date.now(); 
        if(now - startTime >= time) { 
            console.log('误差', now - startTime - time); 
            return; 
        } 
    } 
} 
timer(5000); 
打印:误差 0显然这样的方式很精确,但是我们知道 js 是单线程运行,使用这样的方式强行霸占线程会使得页面进入卡死状态,这样的结果显然是不合适的。
	


functiontimer() { 
   var speed = 500, 
   counter = 1,  
   start = new Date().getTime(); 
    
   functioninstance() 
   { 
    var real = (counter * speed), 
    ideal = (new Date().getTime() - start); 
    
    counter++; 
    var diff = (ideal - real); 
    form.diff.value = diff; 
    window.setTimeout(function() { instance(); }, (speed - diff)); // 通过系统时间进行修复 
   }; 
    
   window.setTimeout(function() { instance(); }, speed); 
} 

