一. 前言
虽然js运行在浏览器中是单线程
的,但是浏览器又是事件驱动 Event Driven
的,浏览器中的很多行为都是异步的,会创建事件并放入执行队列中。
浏览器通过事件循环 Event Loop
来实现异步回调的。由浏览器新开一个线程去完成,一个浏览器至少实现三个常驻线程:
- js引擎线程
- GUI渲染线程
- 事件触发线程
CPU、进程、线程的关系
计算机的核心就是:CPU
,它承担了所有的计算任务。
进程
之间是相互独立的,任意时刻,CPU只能运行一个进程,其他进程都处于非运行状态。
一个进程
可以包括多个线程
,多个线程共享进程的资源。
总的来说:
进程
是cpu资源分配的最小单位(是能拥有资源和独立运行的最小单位)线程
是cpu调度的最小单位(线程是建立在进程的基础上的一次程序运行单位,一个进程中可以有多个线程)- 不同
进程
之间也可以通信,不过代价较大 单线程
与多线程
,都是指在一个进程
内的单和多
浏览器是多进程的
浏览器是多进程的,每个tab页都是一个独立的进程。
浏览器包含的进程:
- 主进程
- 协调控制其他子进程创建销毁
- 浏览器界面的显示,用户的交互,前进,后退,收藏
- 将渲染进程得到的内存中的Bitmap,绘制到用户界面上
- 处理不可见操作:网络请求,文件访问
- 第三方插件进程
- 每种类型的插件对应一个进程,仅当使用该插件的时候才会创建
- GPU进程
- 用于3D绘制
渲染进程
,也就是浏览器内核
- 负责页面渲染,脚本执行,事件处理等
- 每个tab页一个渲染进程
浏览器内核(渲染进程)
渲染进程包含的线程:
GUI渲染线程
- 负责渲染页面,布局和绘制
- 页面需要重绘和回流时,该线程就会执行
- 与js引擎线程互斥,防止渲染结果不可预期
JS引擎线程
- 负责处理解析和执行javascript脚本程序
- 只有一个JS引擎线程(单线程)
- 与GUI渲染线程互斥,防止渲染结果不可预期
事件触发线程
- 用来控制事件循环(鼠标点击、setTimeout、ajax等)
- 当事件满足触发条件时,将事件放入到JS引擎所在的执行队列中
定时触发器线程
- setInterval与setTimeout所在的线程
- 定时任务并不是由JS引擎计时的,是由定时触发线程来计时的
- 计时完毕后,通知事件触发线程
异步http请求线程
- 浏览器有一个单独的线程用于处理AJAX请求
- 当请求完成时,若有回调函数,通知事件触发线程
从Event Loop看js的运行机制
-
js分为
同步任务
和异步任务
-
同步任务
都在js引擎线程上执行,形成执行栈
-
事件触发线程
管理一个任务队列
,异步任务触发条件达成后,将回调事件放到任务队列
中 -
执行栈
中的所有同步任务执行完毕,此时JS引擎线程空闲,系统会读取任务队列
,将可运行的异步任务回调事件添加到执行栈
中,开始执行
宏任务和微任务
二. 参考文档
https://juejin.im/post/5d5b4c2df265da03dd3d73e5#heading-10
https://juejin.im/post/5afbc62151882542af04112d
https://segmentfault.com/a/1190000017554062