JS执行是单线程

单线程是指Js引擎执行Js时只分了一个线程给他执行,也就是执行js时是单线程的。

那么问题来了,什么是线程?进程又是什么?

在分析浏览器的渲染过程之前,我们先了解一下什么是进程和线程:

(1)什么是进程?

进程是CPU进行资源分配的基本单位

(2)什么是线程?

线程是CPU调度的最小单位,是建立在进程的基础上运行的单位,共享进程的内存空间。

多进程

1、浏览器是多进程

2、不同类型的标签页都会开启一个新的进程

3、相同类型的标签页是会合并到一个进程

1、浏览器进程

(1)负责管理各个标签页的创建和销毁

(2)负责浏览器的页面显示和功能(前进,后退,收藏等)

(3)负责资源的管理与下载

2、第三方插件进程

(1)负责每个第三方插件的使用,每个第三方插件使用时候都会创建一个对应的进程

3、GPU进程

(1)负责3D绘制和硬件加速

4、浏览器渲染进程(咱们这回主要分析的)

1、浏览器内核,主要负责HTML,CSS,JS等文件的解析和执行

什么是浏览器内核?

浏览器内核就是浏览器渲染进程,从接收下载文件后再到呈现整个页面的过程,由浏览器渲染进程负责,主要流程如下:

1、解析HTML文件和CSS文件,加载图片等资源文件,渲染成用户看到的页面 2、执行解析js文件脚本代码

这里主要讲浏览器页面渲染过程,在该过程中浏览器渲染进程会开启多个线程协作完成,主要的线程以及作用如下:

1、GUI渲染线程

2、JS引擎线程

3、事件触发线程

4、定时器触发线程

5、异步HTTP请求线程

什么是JS引擎?

1、JS内核,也称JS引擎(例如V8引擎),负责处理执行javascript脚本程序,

2、由于js是单线程(一个Tab页内中无论什么时候都只有一个JS线程在运行JS程序),依靠任务队列来进行js代码的执行,所以js引擎会一直等待着任务队列中任务的到来,然后加以处理。

注意,JavaScript 只在一个线程上运行,不代表 JavaScript 引擎只有一个线程。事实上,JavaScript 引擎有多个线程,单个脚本只能在一个线程上运行(称为主线程),其他线程都是在后台配合

为了利用多核 CPU 的计算能力,HTML5 提出 Web Worker 标准,允许 JavaScript 脚本创建多个线程,但是子线程完全受主线程控制,且不得操作 DOM。所以,这个新标准并没有改变 JavaScript 单线程的本质。

V8引擎的内部结构

1、V8是一个非常复杂的项目,使用cloc统计可知,它竟然有超过100万行C++代码。

2、V8由许多子模块构成,其中这4个模块是最重要的:

1.Parser:负责将JavaScript源码转换为Abstract Syntax Tree (AST)2.Ignition:interpreter,即解释器,负责将AST转换为Bytecode,解释执行Bytecode;3.TurboFan:compiler,即编译器,利用Ignitio所收集的类型信息,将Bytecode转换为优化的汇编代码;4.Orinoco:garbage collector,垃圾回收模块,负责将程序不再需要的内存空间回收;

再次强调:单线程是指Js引擎执行Js时只分了一个线程给他执行,也就是执行js时是单线程的。

既然JS是单线程的,那怎么实现异步的呢?

单线程意味着什么:JavaScript 同时只能执行一个任务,其他任务都必须在后面排队等待。也就是说代码只能同步执行,必须执行上一行才能执行下一行。

console.log('1')
setTimeout(() => {console.log('2')
}, 0);
console.log('3')

然而并不是,还有异步!!!

程序里面所有的任务,可以分成两类:同步任务(synchronous)和异步任务(asynchronous)。

同步任务是那些没有被引擎挂起、在主线程上排队执行的任务。只有前一个任务执行完毕,才能执行后一个任务。

异步任务是那些被引擎放在一边,不进入主线程、而进入任务队列的任务。只有引擎认为某个异步任务可以执行了(比如 Ajax 操作从服务器得到了结果),该任务(采用回调函数的形式)才会进入主线程执行。排在异步任务后面的代码,不用等待异步任务结束会马上运行,也就是说,异步任务不具有“堵塞”效应。

举例来说,Ajax 操作可以当作同步任务处理,也可以当作异步任务处理,由开发者决定。如果是同步任务,主线程就等着 Ajax 操作返回结果,再往下执行;如果是异步任务,主线程在发出 Ajax 请求以后,就直接往下执行,等到 Ajax 操作有了结果,主线程再执行对应的回调函数。

那怎么实现异步的呢?

任务队列和事件循环

JavaScript 运行时,除了一个正在运行的主线程,引擎还提供一个任务队列(task queue),里面是各种需要当前程序处理的异步任务。(实际上,根据异步任务的类型,存在多个任务队列。为了方便理解,这里假设只存在一个队列。)

首先,主线程会去执行所有的同步任务。等到同步任务全部执行完,就会去看任务队列里面的异步任务。如果满足条件,那么异步任务就重新进入主线程开始执行,这时它就变成同步任务了。等到执行完,下一个异步任务再进入主线程开始执行。一旦任务队列清空,程序就结束执行。

异步任务的写法通常是回调函数。一旦异步任务重新进入主线程,就会执行对应的回调函数。如果一个异步任务没有回调函数,就不会进入任务队列,也就是说,不会重新进入主线程,因为没有用回调函数指定下一步的操作。

JavaScript 引擎怎么知道异步任务有没有结果,能不能进入主线程呢?答案就是引擎在不停地检查,一遍又一遍,只要同步任务执行完了,引擎就会去检查那些挂起来的异步任务,是不是可以进入主线程了。这种循环检查的机制,就叫做事件循环(Event Loop)。维基百科的定义是:“事件循环是一个程序结构,用于等待和发送消息和事件(a programming construct that waits for and dispatches events or messages in a program)”。

代码是如何执行的?

宏任务(macro-task)、微任务(micro-task)

除了广义的同步任务和异步任务,JavaScript 单线程中的任务可以细分为宏任务和微任务。

1.macro-task包括:script(整体代码), setTimeout, setInterval, setImmediate, I/O, UI rendering。

2.micro-task包括:process.nextTick, Promises, Object.observe, MutationObserver。

有了宏任务和微任务的概念后,那 JS 的执行顺序是怎样的?是宏任务先还是微任务先?

第一次事件循环中,JavaScript 引擎会把整个 script 代码当成一个宏任务执行,执行完成之后,再检测本次循环中是否寻在微任务,存在的话就依次从微任务的任务队列中读取执行完所有的微任务,再读取宏任务的任务队列中的任务执行,再执行所有的微任务,如此循环。JS 的执行顺序就是每次事件循环中的宏任务-微任务。

彻底理解js是单线程相关推荐

  1. 如何理解JS的单线程?

    JS本质是单线程的.也就是说,它并不能像JAVA语言那样,两个线程并发执行. 但我们平时看到的JS,分明是可以同时运作很多任务的,这又是怎么回事呢? 首先,JS的代码,大致分为两类,同步代码和异步代码 ...

  2. 好程序员web前端分享如何理解JS单线程

    好程序员web前端分享如何理解JS单线程,JS本质是单线程的.也就是说,它并不能像JAVA语言那样,两个线程并发执行. 但我们平时看到的JS,分明是可以同时运作很多任务的,这又是怎么回事呢? 首先,J ...

  3. 为什么JS是单线程?JS中的Event Loop(事件循环)?JS如何实现异步?setimeout?

    https://segmentfault.com/a/1190000012806637 https://www.jianshu.com/p/93d756db8c81 首先,请牢记2点: (1) JS是 ...

  4. 对于怎么理解js中Event Loop,你可以看这篇文章

    javascript中event loop是什么 声明 源文档地址 介绍 如何你跟我一样的话,那么你一定会爱上javascript!虽然它不是一种比较完美的编程语言,但是严格地说,还有其它比javas ...

  5. 工作流 节点子线程_节点JS体系结构–单线程事件循环

    工作流 节点子线程 Today we will look into Node JS Architecture and Single Threaded Event Loop model. In our ...

  6. 彻底理解 JS Event Loop(浏览器环境)

    最近罗列了一些软件开发基础知识点,计划逐一的.彻底的理解每一个知识点,并为每个知识点写一篇详细的,图文并茂的文章.这篇是关于浏览器环境下 JS 的 Event Loop 机制(如有错误,欢迎指出). ...

  7. 理解js中的同步和异步

    首先要先了解下js单线程 一.为什么js是单线程? 其实,JavaScript的单线程,与它的用途是有很大关系,我们都知道,JavaScript作为浏览器的脚本语言,主要用来实现与用户的交互,利用Ja ...

  8. 如何理解js中的同步和异步

    首先需要理解:JS是单线程运行的 同步和异步,无论如何,做事情的时候都是只有一条流水线(单线程),同步和异步的差别就在于这条流水线上各个流程的执行顺序不同. 同步就是程序按照正常的执行顺序,依次执行 ...

  9. 了解EventLoop就明白为何 js 是单线程?| 前端面试基础

    前置概念 在了解 EventLoop 事件循环 前,先铺垫一些基础概念. 堆和栈 堆和栈是计算机领域的术语: 栈(stack)又名堆栈,它是一种运算受限的线性表.限定仅在表尾进行插入和删除操作的线性表 ...

最新文章

  1. oracle 体系结构认识,Oracle数据库体系结构简单认识一
  2. 【音视频架构演进:边缘计算与云原生】
  3. 选修课计算机网络技术,2020智慧职教网络选修课计算机网络技术基础答案完整满分章节测试答案...
  4. 中科大博士写外挂被抓,非法牟利300多万!
  5. HALCON学习之旅(四)
  6. 灰度实战(四):Apollo配置中心(4)
  7. Lomboz插件安装
  8. 虚幻引擎UE4源码编译安装(x86,arm64平台)
  9. Android 融云即时通讯开发
  10. centos7下安装mysql5.7(rpm)
  11. 计算机在职硕士 学什么,计算机在职研究生考什么科目为什么此专业比较强调数学呢...
  12. 计算机网络ip地址分类6,c类ip地址划分6个子网
  13. 怎么刷android10,安卓10的刷机教程,教你刷好Killer的精简包
  14. (廿五)Python爬虫:抓取今日头条图片
  15. 纵向数据中抑郁检测与预测的深度多任务学习
  16. python web py入门(6)-webpy在模板里使用code代码段错误的问题
  17. 河工大邮箱申请,jetbrains学生邮箱申请,ideaIU版本下载、激活
  18. Logic BIST
  19. GitLab删除项目操作(亲测)
  20. C++define宏的边际效应

热门文章

  1. 注意了,这些数值计算的坑千万别踩!
  2. 响应式布局技术:App如何适配不同尺寸的设备
  3. “编程能力差,90%输在了数学上!”骨灰级开发:其实你们都是瞎努力!
  4. 全球呼吸机告急!医疗科技巨头美敦力“开源”设计图和源代码
  5. 知名社交网络 Myspace 丢失 12 年用户数据,大型系统究竟如何做迁移?
  6. 程序员跳槽面试刷题必备,微软工程师放大招!| 程序员硬核评测
  7. 马蓉微博对呛王宝强,结果坑了新浪肥了阿里云
  8. 即将发布的 JDK 11 包含了什么?
  9. 2018 OpenInfra Days China 大咖来袭——开源,我们是认真的
  10. 并发编程应用场景_linux网络编程之select函数的并发限制和poll函数应用举例