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》

JavaScript定时器详解的更多相关文章

  1. JavaScript定时器详解及实例

    JS里设定延时: 使用SetInterval和设定延时函数setTimeout 很类似.setTimeout 运用在延迟一段时间,再进行某项操作. setTimeout("function& ...

  2. JavaScript事件详解-jQuery的事件实现(三)

    正文 本文所涉及到的jQuery版本是3.1.1,可以在压缩包中找到event模块.该篇算是阅读笔记,jQuery代码太长.... Dean Edward的addEvent.js 相对于zepto的e ...

  3. JavaScript事件详解-Zepto的事件实现(二)【新增fastclick阅读笔记】

    正文 作者打字速度实在不咋地,源码部分就用图片代替了,都是截图,本文讲解的Zepto版本是1.2.0,在该版本中的event模块与1.1.6基本一致.此文的fastclick理解上在看过博客园各个大神 ...

  4. JavaScript正则表达式详解(一)正则表达式入门

    JavaScript正则表达式是很多JavaScript开发人员比较头疼的事情,也很多人不愿意学习,只是必要的时候上网查一下就可以啦~本文中详细的把JavaScript正则表达式的用法进行了列表,希望 ...

  5. JavaScript正则表达式详解(二)JavaScript中正则表达式函数详解

    二.JavaScript中正则表达式函数详解(exec, test, match, replace, search, split) 1.使用正则表达式的方法去匹配查找字符串 1.1. exec方法详解 ...

  6. JavaScript事件详解-zepto的事件实现

    zepto的event 可以结合上一篇JavaScript事件详解-原生事件基础(一)综合考虑源码暂且不表,github里还有中文网站都能下到最新版的zepto.整个event模块不长,274行,我们 ...

  7. javascript 函数详解2 -- arguments

    今天我们接着上篇文章来继续javascript函数这个主题.今天要讲的是函数对像中一个很重要的属性--arguments. 相关阅读: javascript 函数详解1 -- 概述 javascrip ...

  8. [原创]JavaScript继承详解

    原文链接:http://www.cnblogs.com/sanshi/archive/2009/07/08/1519036.html 面向对象与基于对象 几乎每个开发人员都有面向对象语言(比如C++. ...

  9. STM32F103的11个定时器详解(转)

    源:STM32F103的11个定时器详解 STM32F103系列的单片机一共有11个定时器,其中:2个高级定时器4个普通定时器2个基本定时器2个看门狗定时器1个系统嘀嗒定时器 出去看门狗定时器和系统滴 ...

随机推荐

  1. Var的用法解析

    C#关键字是伴随着.NET 3.5以后,伴随着匿名函数.LINQ而来, 由编译器帮我们推断具体的类型.总体来说,当一个变量是局部变量(不包括类级别的变量),并且在声明的时候初始化,是使用var关键字的 ...

  2. 前序遍历构造已知二叉树(Java)

    public BiNode createBiTree() { Scanner input = new Scanner(System.in); int k = input.nextInt(); if(k ...

  3. MongoDB之常用操作

    最近经常使用MongoDB来进行数据的操作,特此记录总结一下

  4. Android P添加一个可以让system_server进程访问的hal service需要改动的sepolicy文件

    在device/sepolicy/common目录中: 修改文件attributes: attribute hal_newXX;attribute hal_newXX_client;attribute ...

  5. RSA加解密工具类RSAUtils.java,实现公钥加密私钥解密和私钥解密公钥解密

    package com.geostar.gfstack.cas.util; import org.apache.commons.codec.binary.Base64; import javax.cr ...

  6. Gradle+IDEA使用说明

    Gradle+IDEA使用说明 导语: IDEA拥有大量的JAVA开发者拥护,相比于开源的eclipse,IDEA拥有更简洁直观的界面,拥有更强大的自动补全功能,号称能“一路敲回车完成编码”.如果把I ...

  7. 自定义的AdBlock过滤规则

    自定义的AdBlock过滤规则 # 屏蔽百度首页的广告流 www.baidu.com##DIV[id="u1"] www.baidu.com##DIV[id="qrcod ...

  8. 查看Linux的所有线程

    查看Linux所有线程有3种方法: ps -T <pid>可以看指定pid的所有线程,SPID就是指线程.或者用ps -eLf top -H,和普通的top命令相比,多了Thread ht ...

  9. M-BM-

    今天拷贝了一段代码 struct    Test       {               Test(    int    )    {}               Test()    {}    ...

  10. windows下安装oracle11g测试是否成功与监听器问题和网页控制台登录

    测试步骤1:请执行操作系统级的命令:tnsping orcl 测试步骤 2:请执行操作系统级的命令:sqlplus system/password@orcl 安装完oracle后要启动oracle服务 ...