setTimeout/setInterval

Javascript定时器setTimeout/setInterval有一个非常明显的问题是时间并不精确,参考下例:

假设有以下场景

setTimeout(function timeoutHandler(){
   /*Some timeout handle code that runs for 6ms*/
  }, 10);
  setInterval(function intervalHandler(){
   /*Some interval handle code that runs for 8ms*/
  }, 10);
  const myButton = document.getElementById("myButton");
  myButton.addEventListener("click", function clickHandler(){
   /*Some click handle code that runs for 10ms*/
  }); 

注册延迟执行计时器,延迟10ms。

延迟执行回调函数需要执行6ms。

接着注册一个间隔执行计时器,每隔10ms执行一次。

间隔执行回调函数需要执行8ms。

继续注册一个单击事件处理器,需要执行10ms。

本例中的代码块需要运行18ms。

现在,假设某毫无耐心的用户在程序执行6ms时快速单击按钮。

执行情况:

1、[0ms]执行主线程

2、[6ms]添加点击事件到队列中

3、[10ms]两个计时器按照注册顺序加入宏任务队列

4、[18ms]单击和两个计时器等待触发,单击开始执行

5、[20ms]间隔计时器又一次触发,但是已经有该实例。触发被终止。

6、[28ms]单击事件执行完毕,执行延迟计时器任务。

7、[30ms]间隔计时器又一次触发,但是已经有该实例。触发被终止。

8、[34ms]延迟计时器执行完毕,执行间隔计时器任务。

9、[40ms]间隔计时器又一次触发,间隔处理器正在执行,所以这次可以添加到任务队列。

10、[42ms]间隔计时器执行完毕,执行刚刚添加的间隔计时器。

11、[50ms]间隔计时器执行完毕.间隔计时器又一次触发。添加到任务队列,此后10、11反复执行。

可以看到,定时器并未像预期执行。是因为JavaScript中定时器机制导致。由此引出替代方案requestAnimationFrame。须注意的是,requestAnimationFrame也属于宏任务。

requestAnimationFrame

编辑中。。。

参考文献:

《Secrets of the JavaScript Ninja》

最新文章

  1. Spark Application的调度算法
  2. bash 源码分析
  3. .NET程序员项目开发必知必会—Dev环境中的集成测试用例执行时上下文环境检查(实战)
  4. 使用imeOptions
  5. Navicat for MySQL的使用
  6. HTTP refere
  7. HTML标签大全
  8. U盘装系统出现错误 安装失败怎么办
  9. 用python解析html
  10. Oracle 11g 的PL/SQL函数结果缓存
  11. vmWare虚拟机下ubuntu配置代理上网
  12. gets、scanf和getchar之间的区别
  13. apache 运行php环境之困扰,无法加载多个不同的.html文件
  14. MySQL InnoDB 修改表列Online DDL
  15. node+mysql,实现基本的增删改查,附带跟踪记录和运行时间记录
  16. Redis事务和实现秒杀功能的实现
  17. Jquery 图片延迟加载技术
  18. Flutter开发环境(Window)配置及踩坑记录
  19. FJNU2018低程A 逃跑路线(Lucas + 中国剩余定理 + LGV定理)题解
  20. org.apache.maven.archiver.MavenArchiver.getManifest错误

热门文章

  1. 在Bootstrap开发框架中使用Grid++报表
  2. modelsim10.1a安装破解说明
  3. 小A的柱状图
  4. 关于npm安装报错 网络问题等等等
  5. DAY20、垃圾回收机制,正则模块
  6. Python基础:数据类型-字符串(7)
  7. Python——模块——linecache(对文本行的随机访问)
  8. [模板] tarjan/联通分量/dfs树
  9. html2canvas 识别 svg 解决方案
  10. drf相关问题