zoukankan      html  css  js  c++  java
  • JavaScript中的计时器原理

    理解John Resig 在 How JavaScript Timers Work

    原理分析

    timer(setInterval,setTimeout)有一个很重要的概念,时间延迟的长短是不稳定的。因为所有的javascript都是在单一线程中执行,那些异步的事件(比如说鼠标点击,或者timer)只在执行期出现空闲的时候才会运行。下图能很好的说明这个情况。

    此例中有三个异步事件,鼠标点击,setTimeout,setInterval

    先介绍一下这个图的构成,左侧以10为间隔的横杠是以ms为单位从上至下的时间轴,蓝色的圆角正方形代表正在执行的代码块(这由单线程本质决定,javascript代码是以块运行的)。就比如,第一个模块执行了一些javascript代码,时间约为18ms,第二个模块鼠标点击后执行的函数花了约11ms。

    下面我们详细解释这个图的运行流程和原理。

    从上开始,在3ms(都是近似值)的位置执行了setTimeout(fn,10ms),然后它计时器开始计时;7ms时点击事件触发,立即添加点击回调函数到队列中;10ms执行setInterval(fn,10ms),它的计时器开始计时。下面到13ms时,这时3ms的setTimeout已经计时完毕,触发,它的fn回调函数添加到队列中。第一个块执行完毕。

    此时我们的队列中堆积了我们将要执行的回调函数。依次为鼠标点击回调函数,setTimeout回调函数,取在前的,第二个的代码块将要执行的是鼠标点击的回调函数。开始执行第二个块,运行到20ms时,setInterval事件触发,回调函数添加到队列中。第二个块执行完毕。

    此时我们的队列中有setTimeout,setInterval回调函数。下面执行setTimeout的回调函数。注意!到30ms时,setInterval事件又一次触发,在队列里有相同的回调函数时,这个新的setInterval回调函数会被浏览器忽略掉。第三个块执行完毕。

    此时我们的队列里只有setInterval回调函数,下面执行setInterval的回调函数。到40ms时,setInterval事件触发,使得刚为空的队列里又多了一个setInterval回调函数。第四个块执行完毕。

    此时我们的队列里有setInterval回调函数,执行setInterval回调函数。到结束都没产生任何下面要执行的代码。第五个模块完毕。

    到50ms时,触发setInterval,队列里添加它的回调函数,因为目前没有任何代码块在执行,所以队列的代码直接执行。

    三个异步事件的执行情况:

    鼠标点击7ms触发,18ms才执行。

    setTimeout,3ms开始,13ms触发,29ms才执行回调函数。

    setInterval,10ms开始,20ms触发,30ms触发被丢弃,36ms执行回调函数;40ms触发,41ms执行回调函数;50ms触发,50ms执行回调函数。

    下面给出setTimeout的测试实例

    function a() {
      setTimeout(function(){console.log(1)},0)
      console.log(2)
    }
    a()//2
       //1
    function(){console.log(1)}被放在了一个下一个块中。

    下面是对上述原理的总结

    • JavaScript引擎只有一个线程,这使得异步事件必需列队等待执行。
    • setTimeout一定会和setInterval在如何执行代码上有着本质地区别。
    • 如果一个timer在将要执行的时候被阻塞,它将会等待下一个时机(比预期的延时要长)。
    • 如果interval的执行时间较长(比指定的延时长),那么它们将连续地执行而没有延时。

    原理利用

    先简单讲一下在javascript中,假如大量修改DOM的操作,在内存富裕的情况,DOM会操作被分成最小片,约莫两三个操作,然后在浏览器渲染一次页面。而在内存吃紧的情况,浏览器会将许多DOM操作合并到一起,再渲染页面,以提高效率,而我们的js操作

    一时没找到很好的实例,

  • 相关阅读:
    vue移动端适配问题
    excel 表格数据转json格式
    常用快捷键
    微信公众号监听返回事件
    总结css常用方法
    封装axios
    初学angular项目中遇到的一些问题
    jquery项目中一些常用方法
    怎样做ie兼容性
    vue事件修饰符
  • 原文地址:https://www.cnblogs.com/winderby/p/4054732.html
Copyright © 2011-2022 走看看