一、事件环的相关基本概念认知
前言:
Event Loop非常适合在面试中处理一些特别复杂的异步+同步任务程序。
但是我们本身需要了解async await
、promise
、setTimeout
…背后的逻辑道理,清除Event Loop背后这些知识的。
一、进程
1.1 定义及浏览器页面中的进程
进程定义:系统进行资源分配和调度的基本单位。
线程定义:进程内一个相对独立的,可调度的执行单元。
浏览器是一个多进程的应用程序。
每个进程中包含多个线程,线程在进程中运行。
对于浏览器来说:
-
浏览器有一个主进程——>用户界面
-
每个Tab(标签页)都会开启一个进程
-
每个Tab(标签页)各自有独立的:
-
渲染进程(浏览器内核Renderer=渲染引擎)
-
网络进程(网络请求)
-
GPU进程(动画与3D绘制)
例如:css3中translate属性会开启GPU加速
-
插件进程(devtool)
-
注: 为什么分进程?——>降低程序之间的耦合,使用时互不影响。
1.2 渲染进程
其中分为:
-
GUI渲染线程——>渲染页面(解析HTML,CSS、构建DOM/Render树、初始布局与绘制、重绘与回流)
-
JS引擎线程——>解析和运行JS代码
-
事件触发线程——>Event Loop线程
-
事件线程——>用户交互事件、setTimeout、Ajax
特点:GUI渲染线程与JS引擎线程运行互斥,WHY:
JS引擎执行的脚本代码里很可能会有DOM操作,如果不互斥的话会与GUI渲染引擎渲染页面冲突。
1.2.1 JS引擎线程
一个浏览器页面只有一个JS引擎线程(单线程的),但是是一个主线程与多个辅助线程配合。
js引擎单线程原因?:
解除渲染和执行脚本之间的耦合关系,即GUI线程渲染时JS引擎不可以操作DOM。
…还有呢?
留一下问题
1.2.2 事件触发线程(Event Loop线程)
单独的线程独立完成Event Loop:每一个任务(宏任务、微任务)看做是事件触发,event loop把要执行的任务放入执行栈执行。
详情见:事件环笔记。
注:一个个事件由独立线程去完成:用户交互事件、setTimeout、Ajax…
不同事件执行时,都会是不同的线程处理吗?例如点击事件与键盘事件是同一个线程执行吗?我觉得不是…
1.3 宏任务和微任务:
前提:
创建线程的目的是为了实现异步的执行条件:同时,独立的完成任务。
创建进程的目的是为了区分程序任务,互相独立,互不干扰。
宏任务:宿主环境(浏览器,node环境)提供的异步方法和任务:
-
浏览器环境:
<script>
的执行、setTimeout、UI渲染、AJAX、用户触发的事件… -
node环境:setImmediate、process.next、tick…等待补充
微任务:语言标准(EMCA262)提供的API。
- Promise、MutationObserver…
Promise的重点在于处理Promis.then回调 。Promise是同步的,Promis.then里的回调是异步的。
Promise是微任务,但只有Promise.then方法触发才会进入微任务队列。
为什么区分:执行优先级。微任务>宏任务