如果阻止回调,则setInterval的行为不同

时间:2018-01-05 23:10:23

标签: javascript browser callback cross-browser

我在Firefox 58和Linux 63上的Chrome 63中运行相同的代码

count = 0
intv = 0
function f(){
    let a
    console.log('start', performance.now())
    for (let i=0;i<50000000;i++){
        a=i
    }
    if (count % 5 === 0){
        for (let i=0;i<100000000;i++){
            a=i
        }
    }
    console.log('end', performance.now())
    count++
}
function k(){
    intv=setInterval(f, 100)
}
function e(){
    clearInterval(intv)
}

k()

两个常量的确切值可能需要调整以确保第二次和第三次回调被阻止 在Firefox中我得到了

start 2657023.3000000003
end 2657123.92
start 2657124.2800000003
end 2657155.84
start 2657224.2
end 2657265.06
start 2657324.62
end 2657363.3000000003
start 2657424.72
end 2657461.6
start 2657524.94
end 2657624.7800000003

如你所见,从第3次开始的每次回调都是从第2次回调开始的100ms * N

在Chrome中

start 463571.0300000001
end 464149.28
start 464150.49500000005
end 464178.63000000006
start 464178.775
end 464204.61500000005
start 464270.91000000003
end 464308.09
start 464370.94
end 464415.37500000006
start 464470.93500000006
end 464511.48000000004

每次回调都是在第一次回调的100ms * N时执行的

这两个浏览器实现的setInterval之一是错误的还是setInterval的行为依赖于实现?

1 个答案:

答案 0 :(得分:1)

setInterval / setTimeout的确切行为取决于实施情况。除了MDN)和HTML5更新草案(也在评论中引用)中讨论的浏览器和上下文之间的差异。

HTML文档包含注释和步骤,表明在不应该使用计时器时标准的准确性:

  

此API不保证计时器将按计划完全启动。由于CPU负载,其他任务等原因导致延迟。

  
      
  1. (可选)等待另一个用户代理定义的时间长度。
  2.   

特定JavaScript引擎的行为也会影响时间:

  • 运行时分析和代码优化可以随着时间的推移改变和提高特定代码段的速度,
  • 间歇性垃圾收集有时会降低代码速度,而不会影响其他代码,
  • 运行时环境可以动态地改变引擎调用计时器回调的能力。在打开30个标签的低速笔记本电脑上进行定时可能与使用单个标签打开的高速处理器完全不同,没有其他应用程序在运行,也不需要操作系统来分页内存。

我在Firefox中进行性能测试的个人经验是,它非常难以预测。如果测试顺序相反,则通过计时比较两个代码算法会产生不同的结果。例如,第一个算法首先运行似乎更快,但如果第二个算法首先运行它似乎更快。或者多次运行性能测试会产生各种各样的结果。

我对这些变幻莫测的回应是以不同的顺序多次进行性能测试,并使用结果的统计测量作为指南来表现。最快的时间可能表示代码可以运行的速度有多快,平均值可能是更好的实际指南,而最慢的时间,特别是如果它是系列中的第一个,可能是典型的代码只运行一次。