闽公网安备 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);
}

