setTimeout初探(一):4ms的真伪

      看了很多技术文章,大多都信誓旦旦地说setTimeout(f, 0)语句中的f方法会在4ms之后执行,以至于小组很多成员都深信不疑,我决定亲手来验证一下4ms的真伪,代码如下:

//  定义单次调用函数  
function testTimeout() {
    //  启动任务计时器
    console.time("Timeout")
    //  启动浏览器定时任务 
    setTimeout(function() {
        //  统计任务消耗的时间
        console.timeEnd("Timeout")
    }, 0)
}
//  调用函数
testTimeout();

      为了消除任务队列的干扰,我在代码里消除了其他所有的JS代码,仅仅保留了此段代码,然而运行结果依旧让我大吃一惊,消耗的时间竟然高达87ms,有时甚至达到了153ms。
      满脑子都是问号,时间都去哪儿了?时间都去哪儿了?时间都去哪儿了?
      继续改进自己的测试代码,添加多次定时任务,看看它们之间的间隔是否依旧这么惊人,如下:

//  添加循环时间任务
//  count : Number 循环次数
function testTimeouts(count) {
   //  开始计时 
   console.time("Timeouts");
   //  派发单次任务
   function testTimeout() {
       if(count > -1) {
           //  派发循环任务
           setTimeout(testTimeout, 0)
           count --;
       } else {
           //  结束计时
           console.timeEnd("Timeouts")
       }
    }
    testTimeout();
}
//  执行10计时计算
testTimeouts(10);

      执行结果依旧让我难以理解,只有100ms,执行十次setTimeout任务竟然又只有100ms,怎么看与前面单次的测算结果也不存在乘数关系,这是怎么了?
      继续执行20次、30次、40次的定时任务,返回的结果分别是171、215、269,好像依旧没有什么明确的等差关系,模模糊糊觉得可能有50ms的时差,50ms除以10,难道这就是真相?
      再次改进测试代码,在页面添加一个id为test按钮,然后为此按钮注册事件,代码如下:

 document.getElementById("test").addEventListener("click", function() {
     //  执行单次定时任务
     testTimeout();
     //  执行多次定时任务
     //testTimeouts(10);
 });

      这次的测试结果更让我吃惊,单次定时任务仅仅只需要1ms左右的时间,10次、20次、30次、40次的执行时间分别为32ms、72ms、113ms与154ms,难道这次循环定时就是4ms的铁证?

总结

1. setTimeout与4ms真的没什么关系,仅仅在最后循环定时任务中表现出了很大约的约等于关系;
2. setTimeout时间参数的准确性存疑,并不会严格按照约定的时间执行;
3. setTimeout的定时任务机制容易受到任务队列的影响,可参见下面的补充测试;

消失的时间去了哪里?如何保证时间任务的准确性?多个时间任务并发时,浏览器又有多少个时间任务队列?请看后续文章setTimeout初探(二):延迟与跳帧

补充测试

function testTimeout(label) {
    console.time(label)
    setTimeout(function() {
        console.timeEnd(label)
    }, 0)
}
//  S1需要的时间为97ms
testTimeout("S1");
window.onload = function() {
    //  S2需要的时间仅为64ms
    testTimeout("S2");
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值