JavaScript一大特点就是单线程,即同一时间只能做一件事。
这与js的用途有关,早起作为浏览器脚本语言,js的主要用途是与用户互动,以及操作DOM,这决定了只能是单线程,否则会带来复杂的同步问题。
比如,假定js同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,此时浏览器应该以哪个线程为准?
js有worker线程,这是为了利用多核CPU的计算能力,HTML5提出web worker标准,允许js脚本创建多个线程,但子线程是完全受主线程控制的,而且不得操作DOM,所以这个标准并未改变js是单线程的本质。
进程与线程
进程:是CPU资源分配的最小单位。字面意思就是进行中的程序,可理解为一个可以独立运行且拥有自己的资源空间的程序任务。
线程:是CPU调度的最小单位。线程是建立在进程的基础上的一个程序运行单位。 一个线程可以有多个线程;一个进程只有一个执行流称作单线程;一个进程中有多个执行流称作多线程。
浏览器
浏览器是多进程多线程的应用程序
为了避免互相影响,为了减少连环崩溃的几率,当启动浏览器后,会自动启动多个进程。
浏览器包含哪些进程:
-
1、浏览器进程: 主要负责界面显示,用户交互,子进程管理等。浏览器进程内部会启动多个线程处理不同的任务。
-
2、网络进程 负责加载网络资源。网络进程内部会启动多个线程来处理不同的网络任务。
-
3、渲染进程(重点) 渲染进程启动后,会开启一个渲染主进程,主线程负责执行HTML,CSS,JS代码。默认情况下,浏览器会为每一个标签页开启一个新的渲染进程,以保证不同的标签页之间不互相影响。
渲染主线程是如何工作的?
渲染主线程是浏览器最繁忙的线程,需要它处理的任务包括但不限于
- 解析HTML
- 解析CSS
- 计算样式
- 布局
- 处理图层
- 每秒把页面画60次
- 执行全局JS代码
- 执行事件处理函数
- 执行计时器的回调函数
- ...
主线程如何调度任务:=> 排队
以下整个过程,被称之为事件循环(消息循环)
- 1、在最开始的时候,渲染主线程会进入一个无限循环;
- 2、每一次循环会检查消息队列(事件队列)中是否有任务存在。如果有就取出第一个任务执行,执行完一个后进入下一次循环;如果没有,则进入休眠状态。
- 3、其他所有线程(包括其他进程的线程)可以随时向消息队列添加任务。新任务会加到消息队列的末尾。在添加新任务时,如果主线程是休眠状态,则会将其唤醒以继续循环拿任务