52.事件循环机制
题目描述
事件循环机制(宏任务与微任务、执行栈、执行一个宏任务就清空一次微任务队列,然后 再执行宏任务)
什么是事件循环?
- 事件循环是浏览器或
Node
的一种解决javaScript
单线程运行时不会阻塞的一种机制,也就是我们经常使用异步的原理。 - 用于协调事件、用户交互、
JavaScript
脚本、DOM
渲染、网络请求等等的执行顺序问题。一个遵循ECMAScript
标准的代理(浏览器或 JS 引擎)也必须遵循事件循环机制。 - 事件循环是由一个或以上的
任务队列
组成的。
什么是任务队列?
- 任务队列是一个先进先出的数据结构,排在前面的事件,优先被主线程读取。主线程的读取过程基本上是自动的,只要执行栈一清空,
EventLoop
就会从任务队列中读取事件,这个过程是循环不断的,所以整个的这种运行机制又称为Event Loop
(事件循环)。 - 任务队列又分为
宏任务队列
和微任务
队列,当当前执行栈执行完毕时会立刻先处理所有微任务队列中的事件,然后再去宏任务队列中取出一个事件。同一次事件循环中,微任务
永远在宏任务
之前执行。
什么是微任务?
微任务
可以理解是在当前task
执行结束后立即执行的任务。也就是说,在当前任务后,下一个task
之前,在渲染之前。- 所以它的响应速度相比
setTimeout
(setTimeout
是task
,setTimeout
的回调函数是macrotask
)会更快,因为无需等渲染。 微任务
包括Promise
的回调函数、MutaionObserver
的回调函数、process.nextTick
(Node
独有)。
什么是宏任务?
宏任务
可以理解是每次执行栈执行的代码就是一个宏任务(包括每次从事件队列中获取一个事件回调并放到执行栈中执行)。- 浏览器为了能够使得
JS
内部macrotask
与DOM
任务能够有序的执行,会在一个macrotask
执行结束后,在下一个macrotask
执行开始前,对页面进行重新渲染,流程如下:
事件循环机制
执行顺序:nextTick → Promise.then → setTimeout 微任务优先于宏任务,nextTick 是微任务中的最高优先级