• js引擎单线程机制


    js引擎解析:

    http://www.(搜狐)suchso.com/projecteactual/Javascript-setTimeout-timer.html

    时间延迟不能被保证。什么意思,就是说你这样写setTimeout(fn, 500)并不代表fn肯定在500毫秒之后马上就执行,延迟很可能会更长。因为 JavaScript 是单线程语言,所有的异步事件(包括计时器、鼠标事件或者一个 XMLHttpRequest 完成)仅仅当程序执行期间有缺口的时候才会执行,不是你规定了什么时候就什么时候执行,要知道程序员不是万能的,你写的东西最终还是要看浏览器脸色的。

     笔者注:js是一个单线程的语言,他的事件执行机制可以看成是 排队 。(这个概念是我在一个博文上阮一峰大神的博客:http://www.ruanyifeng.com/blog/2012/12/asynchronous%EF%BC%BFjavascript.html)

     讲一个常问的问题,setTimeout(fn ,0 ),

    这个fn不会立即执行,第一个是浏览器的更新频率限制了,第二个是js引擎的事件队列机制。

    浏览器内核实现允许多个线程异步执行,这些线程在内核制控下相互配合以保持同步.

    假如某一浏览器内核的实现至少有三个常驻线 程:javascript引擎线程,界面渲染线程,浏览器事件触发线程,除些以外,也有一些执行完就终止的线程,如Http请求线程,

    这些异步线程都会产生不同的异步事件,

    下面通过一个图来阐明单线程的JavaScript引擎与另外那些线程是怎样互动通信的.

    虽然每个浏览器内核实现细节不同,但这其中的 调用原理都是大同小异.

    由图可看出,浏览器中的JavaScript引擎是基于事件驱动的,这里的事件可看作是浏览器派给它的各种任务,

    这些任务可以源自 JavaScript引擎当前执行的代码块,如调用setTimeout添加一个任务,也可来自浏览器内核的其它线程,

    如界面元素鼠标点击事件,定时触发 器时间到达通知,异步请求状态变更通知等.

    从代码角度看来任务实体就是各种回调函数,JavaScript引擎一直等待着任务队列中任务的到来.由于单线 程关系,这些任务得进行排队,一个接着一个被引擎处理.

    IE8及其之前的IE版本更新间隔为15.6毫秒。假设你设定的setTimeout延迟为16.7ms,那么它要更新两个15.6毫秒才会该触发延时。这也意味着无故延迟了 15.6 x 2 - 16.7 = 14.5毫秒。
    
               16.7ms
    DELAY: |------------|
    
    CLOCK: |----------|----------|
             15.6ms    15.6ms
    
    所以即使你给setTimeout设定的延时为0ms,它也不会立即触发。目前Chrome与IE9+浏览器的更新频率都为4ms(如果你使用的是笔记本电脑,并且在使用电池而非电源的模式下,为了节省资源,浏览器会将更新频率切换至于系统时间相同,也就意味着更新频率更低)。
    
    退一步说,假使timer resolution能够达到16.7ms,它还要面临一个异步队列的问题。因为异步的关系setTimeout中的回调函数并非立即执行,而是需要加入等待队列中。但问题是,如果在等待延迟触发的过程中,有新的同步脚本需要执行,那么同步脚本不会排在timer的回调之后,而是立即执行.

    延迟器setTimeout和定时器setInterval的区别

      setTimeout(function(){
        /* Some long block of code... */
        setTimeout(arguments.callee, 10);
      }, 10);
      
      setInterval(function(){
        /* Some long block of code... */
      }, 10);
    
     
    这两句代码乍一看没什么差别,但是它们是不同的。
    setTimeout回调函数的执行和上一次执行之间的间隔至少有10ms(可能会更多,但不会少于10ms),而setInterval的回调函数将尝试每隔10ms执行一次,不论上次是否执行完毕。 在这里我们学到了很多知识,总结一下: JavaScript引擎是单线程的,强制所有的异步事件排队等待执行 setTimeout 和 setInterval 在执行异步代码的时候有着根本的不同 如果一个计时器setTimeout被阻塞而不能立即执行,它将延迟执行直到下一次可能执行的时间点才被执行(比期望的时间间隔要长些) 如果setInterval回调函数的执行时间将足够长(比指定的时间间隔长),它们将连续执行并且彼此之间没有时间间隔
  • 相关阅读:
    Struts2 技术全总结 (正在更新)
    Servlet 技术全总结 (已完成,不定期增加内容)
    字节顺序&字节对齐
    Kubernetes 清除持续 Terminating 状态的Pods
    [K8s]无yaml文件重启Pod
    外部访问docker容器(docker run -p/-P 指令)
    Linux (OpenBSD)系统目录分析
    CPU Cache 机制以及 Cache miss
    ifconfig 中的 eth0 eth0:1 eth0.1 与 lo
    MYSQL 文件类型
  • 原文地址:https://www.cnblogs.com/shixiaomiao/p/4805767.html
Copyright © 2020-2023  润新知