面试必备系列之JS的事件循环机制
如果你翻阅一本介绍 JS 的书籍,一定会告诉你下面这句话 “JS 是一门单线程语言。JS 的异步事件通过 事件队列 来实现,事件队列通过 事件循环机制 来控制”。那么今天就来理一理什么是 JS 的事件循环机制。
先告诉你结果,宏任务 -> 微任务 ->…
知识储备
接下来你需要确保知道这几个知识点:
- CPU
作为计算机系统的运算和控制核心,是信息处理、程序运行的最终执行单元。 - 进程
是系统进行资源分配和调度的基本单位;
进程之间相互独立,单核 CPU 在同一时间只能处理一个进程,其他进程处于非运行状态;
并发则是 CPU 使用 时间片轮转调度算法 实现同时运行多个进程; - 线程
是系统能够进行运算调度的最小单位;
一个进程可以包括多个线程,多个线程共享进程资源;
单线程与多线程,都是指在一个进程内的单和多; - 浏览器的多进程
- 事件触发
当事件被触发时,将该事件放入 JS 引擎队列中,等待 JS 引擎处理; - JavaScript引擎
基于事件驱动的单线程,主要负责执行处理解析和执行 执行栈中的 JS 程序; - GUI渲染
主要负责渲染界面,比如回流和重绘操作;
- 事件触发
事件循环原理
EventLoop 其实就是 JS 引擎管理事件执行的一个流程,具体执行顺序是由环境决定的,目前 JS 运行环境有两个,分别是浏览器和nodeJS。
事件循环又分为同步任务和异步任务
- 同步任务:在主线程上执行的任务,从上到下依次执行
- 异步任务:不在主线程,在任务队列的任务。只有主线程没有任务,任务队列里的异步任务才会进入主线程执行
- 异步任务又分为宏任务和微任务
- 宏任务:script、setTimeout、setInterval、交互等
- 微任务:new Promise().then、nextTick;若promise和nextTick,则先执行nextTick
执行顺序
- 主线程从上到下依次执行同步任务;
- 遇到宏任务则宏任务放入宏任务队列中;
- 遇到微任务则微任务放入微任务队列中;
- 所有同步代码执行完;
- 微任务调入主线程执行;
- 微任务执行完毕,将宏任务调入主线程执行;
- 一直循环到所有任务执行完毕;
接下来练习一下掌握程度
setTimeout(()=>{
new Promise(resolve =>{
resolve();
}).then(()=>{
console.log('5');
});
console.log(4);
});
new Promise(resolve => {
resolve();
console.log(1)
}).then( () => {
console.log(3);
Promise.resolve().then(() => {
console.log('6');
}).then(() => {
Promise.resolve().then(() => {
console.log('7')
})
})
})
console.log(2);
//输出:1 2 3 6 7 4 5