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. CodeSmith 二、多模板按目录树批量自动生成代码

    通过调用指定目录下的所有模板,逐一按照数据表生成独立的代码文件.支持多模板调用.支持所有数据表生成或批量指定多个生成.支持自动的文件目录结构.支持代码文件格式化命名等. 背景:最近一个新项目一高兴选了 ...

  2. 玩玩LED点阵屏(arduino nano)

    做些记录,特别是led显示左移效果的代码,二进制位的特效函数 unsigned ][]= { 0xff,0xd7,0x83,0xd6,0xc6,0xd4,0xc6,0x82,0xd6,0xba,0xf ...

  3. 算法笔记-exgcd

    扩展欧几里得 扩展欧几里德算法是用来在已知a, b求解一组x,y, 使它们满足贝祖等式: ax+by = gcd(a, b) =d(解一定存在,根据数论中的相关定理). 扩展欧几里德常用在求解模线性方 ...

  4. java基础-04泛型

    介绍 泛型就是数据类型的参数化表示,泛型的本质是参数化类型,常用E代表任何数据类型,在实际使用的时候把实际的数据类型传递给E. 泛型的好处是设计通用的功能,多个数据类型可以共用. 泛型类型E只能代表O ...

  5. Springboot集成Redis步骤

    Spring boot 集成Redis的步骤如下: 1.在pom.xml中配置相关的jar依赖: <!--加载spring boot redis包 --> <dependency&g ...

  6. MR-join连接

    package com.bw.mr; import java.io.BufferedReader; import java.io.IOException; import java.io.InputSt ...

  7. pytorch识别CIFAR10:训练ResNet-34(微调网络,准确率提升到85%)

    版权声明:本文为博主原创文章,欢迎转载,并请注明出处.联系方式:460356155@qq.com 在前一篇中的ResNet-34残差网络,经过训练准确率只达到80%. 这里对网络做点小修改,在最开始的 ...

  8. 调用webservice帮助类

    using System;using System.CodeDom;using System.CodeDom.Compiler;using System.Collections.Generic;usi ...

  9. Tutorial: Create a Windows Machine Learning UWP application (C#)

    In this tutorial, we'll build a simple Universal Windows Platform application that uses a trained ma ...

  10. MVC autofac 属性注入

    Global文件 public class MvcApplication : System.Web.HttpApplication { private static IContainer Contai ...