前言
本文我们将会介绍js实现
异步
的原理即Event Loop。Event Loop 即事件循环,是指浏览器或Node
的一种解决javaScript
单线程运行时不会阻塞的一种机制。
为什么要明白什么是Event Loop
- 增加自己的技术深度,懂得JavaScript的运行机制。
- 以不变应万变,前端领域快速发展新生代技术层出不穷,掌握底层原理保持自己的核心竞争力。
- 应对面试,知其原理,任期发挥。
- Vue高效的秘诀就是一套批量,异步的更新策略,底层就是使用了Event Loop。
相关知识
堆
- 堆是一种数据结构,堆是一种线性结构,相当于一维数组,有唯一后继。
栈
- 栈是只能在某一端插入和删除的特殊线性表。先进后出。
队列
- 特殊之处在于它只允许在表的前端(
front
)进行删除操作,而在表的后端(rear
)进行插入操作,和栈一样,队列是一种操作受限制的线性表。
浏览器的事件循环EventLoop
- 浏览器为了协调事件处理、脚本执行、网络请求和渲染等任务而制定的工作机制。
- 在JavaScript中,任务分为两种,一种是宏任务,一种是微任务。
宏任务和微任务
宏任务
- 代表一个个离散的,独立工作的单元。浏览器完成一个宏任务,在下一个宏任务执行开始前,会堆页面进行重新渲染 。
- script全部代码, setTimeout, setInterval, setImmediate(浏览器暂时不支持,目前只支持IE)等。
微任务
- 微任务是更小的任务,是在当前宏任务执行结束后立即执行的任务,如果存在微任务,浏览器会清空微任务之后再重新渲染。
- Promise回调函数, DOM变化,MutationObserver等。
EventLoop的执行过程
JavaScript执行过程
console.log('script start');
setTimeout(function () {
console.log('setTimeout');
}, 0);
Promise.resolve()
.then(function () {
console.log('promise1');
})
.then(function () {
console.log('promise2');
});
console.log('script end');
// 输出结果: script start, script end, promise1, promise2, setTimeout
- 浏览器开始执行时会先执行script脚本。开始逐行解读。
- 识别是同步代码之后直接执行。
- 识别是异步代码之后判断是宏任务还是微任务,宏任务进入宏任务队列中,微任务进入微任务队列中。
- 执行完同步代码之后开始处理微任务队列。
- 执行完微任务队列的时候这个时候浏览器属于空闲状态开始执行宏任务。
- 宏任务队列中的任务完之后,一次Event Loop就执行完毕。
结语
关于社区有很多声音说浏览器是先执行微任务在执行宏任务。浏览器是先执行微任务之后在去执行宏任务,script就是一个宏任务但是 刚开始进入程序时先去执行微任务,但是微任务队列中没有任务就执行script脚本。浏览器开始执行script就会创建执行代码JS stack, 存储微任务的Microtasks,存储宏任务的Tasks。浏览器会先从JS stack开始执行,执行完之后在开始执行Microtasks的微任务,微任务执行完之后在执行Tasks宏任务,执行完毕之后JS stack, Microtasks, Tasks都没有任务,Event Loop结束。
如果文章对大家有帮助,请大家点赞👍关注,评论。