前端进阶攻略之事件循环&ES6事件队列
事件循环与任务队列是JS中比较重要的两个概念。这两个概念在ES5和ES6两个标准中有不同的实现。尤其在ES6标准中,清楚的区分宏观任务队列和微观任务队列才能解释Promise一些看似奇怪的表现。
一.事件循环
1.浏览器宿主环境有5个线程:
- 1.1.JS引擎 (js主线程)
- 1.2.GUI线程(布局引擎,负责渲染浏览器界面,解析HTML,CSS,构建DOM树和RenderObject树,布局和绘制等)互斥状态,相互等待
- 1.3.事件监听线程(onclick)
- 1.4.计时线程(setTimeout)
- 1.5.网络线程(http ,Ajax)
*
2. 什么是事件循环:
总所周知JS是单线程(异步)
优点:不会有线程冲突
缺点:同步应用程序的开发比较容易,但由于需要在上一个任务完成后才能开始新的任务,所以其效率通常比多线程应用程序低。如果完成同步任务所用的时间比预计时间长,应用程序可能会不响应,一句话来讲就是效率慢。
当2345线程发生了一些事情,如果该线程发现,就会处理这些事情,这些线程需要处理的事情加到一个事件队列(内存)中。 当js引擎(js主线程)发现,执行栈里面没有任何内容的时候,才会去从事件队列中拿出一个程序加到自己的执行栈中JS引擎(js主线程)从事件队列中取出来执行,以及和宿主环境相配合,称为事件循环。
JS引擎是单线程,负责执行JS代码的。
2.1JS分为同步任务和异步任务
2.2同步任务都在主线程上执行,形成一个执行栈
2.3主线程之外,事件触发线程管理着一个任务队列,只要异步任务有了运行结果,就在任务队列之中放置一个事件。
2.4一旦执行栈中的所有同步任务执行完毕(此时JS引擎空闲),系统就会读取任务队列,将可运行的异步任务添加到可执行栈中,开始执行。
二.事件队列
在ES6中,有一个新的概念建立在事件循环队列之上,叫作任务队列。这个概念给大家带来的最大影响可能是Promise的异步特性。
事件队列又分为macro-task(宏任务)与 micro-task(微任务):
宏任务:
script(整体代码)
setTimeout
setInterval
微任务:
Promise
还有其他的微任务,咱们暂时先不管。