zoukankan      html  css  js  c++  java
  • JS-运行机制

    参考自:https://juejin.im/post/6844903805063004167 和 https://www.cnblogs.com/fly_dragon/p/8669057.html,如有侵权,请联系删除。

    一  JavaScript 单线程

    浏览器多线程:

      GUI渲染线程:负责渲染HTML元素,与JS引擎线程是互斥的,当执行JS脚本时,GUI渲染线程被挂起。

      JS引擎线程:负责解析和执行JS脚本,与GUI线程是互斥的,一个tab页无论何时都只有一个JS线程在运行JS程序。

      事件触发线程:用来控制事件轮训,当JS代码中触发了DOM的事件,会将事件对应的任务添加到事件触发线程的任务队列中,直到JS引擎空闲下来再按照队列的顺序逐一处理事件触发线程的任务。

      定时器线程:setInterval与setTimeout所在的线程,该线程完成定时器的定时。

      异步http请求线程:在XMLHttpRequest在连接后是通过浏览器新开一个线程请求, 将检测到状态变更时,如果设置有回调函数,异步线程就产生状态变更事件放到 JavaScript引擎的处理队列中等待处理。

    JS单线程:即上述JS引擎单线程。为什么要单线程?因为多线程处理DOM会产生冲突,虽然可以加锁机制但是所机制,单会带来更大的复杂性。

    #为了多核CPU的计算能力,HTML5提出Web Worker标准,允许JavaScript脚本创建多个线程,但是子线程完全受主线程控制,且不得操作DOM。所以,这个新标准并没有改变JavaScript单线程的本质。
    #JS 引擎只是任意的 JS 代码按需执行的环境。是它周围的环境来调度这些事件(JS 代码执行)。,其他周围环境就是指的在同一进程下的不同的线程,比如事件触发线程、定时器线程等(JS引擎是被宿主环境调度去执行JS的)

    二  任务队列

    任务队列:队列里面存放着各种任务和事件。

      宏任务队列macro-task,在ES5中又称为task。

      微任务队列micro-task,在ES5中又称为job。

    任务:

      同步任务synchronous,按照队列顺序阻塞式执行的

      异步任务asynchronous非阻塞式执行的,使用场景:应用于任务耗时较长或者不确定的场景。常见的异步任务:1.DOM事件 2. setTimeout 3.setInterval 4.异步函数

    三  setTimeout 和 setInterval 的运行机制

    setTimeout 和 setInterval的运行机制:将指定的代码移出本次Event loop 执行。等本次同步代码执行完以后,判断是否到达设定时间,如达到设定时间则执行setTimeout 和 setInterval 中的代码,若未达到设定时间,等待下一轮Event loop继续判断。

    类似案例:addEventListener()方法监听点击事件click,点击进入“假死”状态,其实就是等待队列中的同步任务执行完成,才能够执行异步代码。

    案例一:输出结果为: ‘A’,因为任务队列中的同步任务代码陷入死循环,无法执行到异步任务。

    console.log('A');

    setTimeout(function () {

      console.log('B');

    }, 0);

    while (1) {}

    案例二:输出结果为: 4 4 4 4

    for (var i = 0; i < 4; i++) {

       setTimeout(function () { //执行到异步任务时,只是将异步任务交给定时器(即使设置为0,也是4s),当定时时间到,定时器把异步任务交给异步队列。

        console.log(i); //执行此步时,for同步代码已经执行完成,i传入4次故此时的i=4

       }, 1000);

    }

    案例三:输出结果为: 1 2 3 4 ,let 可定义块级作用域变量,每次for循环的循环体,都是一个全新独立的块作用域,let声明的变量传到for循环体内以后,作用域外部无法更改

    for (let i = 0; i < 4; i++) {

       setTimeout(function () {   //执行到异步任务时,只是将异步任务交给定时器(即使设置为0,也是4s),当定时时间到,定时器把异步任务交给异步队列

        console.log(i); //执行此步时,for同步代码已经执行完成,但是每次传入的let i无法被其他循环代码更改,保持1 2 3 4 

       }, 1000);

    }

  • 相关阅读:
    WinDbg 图形界面功能(一)
    WinDbg的安装、配置和功能
    windbg调试托管代码 .Net clr
    win32线程栈溢出问题 (二)
    win32线程栈溢出问题 (一)
    WinDbg常用命令系列---查看线程调用栈命令K*简介
    BCD码
    Intel 80386 CPU
    Intel 80286 CPU
    Intel 8086 CPU
  • 原文地址:https://www.cnblogs.com/zhoujie0710/p/13826582.html
Copyright © 2011-2022 走看看