目录

  • 事件循环机制
  • 宏任务与微任务
  • 实例分析
  • 参考

1.事件循环机制

浏览器执行JS代码大致可以分为三个步骤,而这三个步骤的往复构成了JS的事件循环机制(如图)。

第一步:主线程(JS引擎线程)中执行JS整体代码或回调函数(也就是宏任务),执行过程中会将对象存储到堆(heap)中,将函数的参数和局部变量加入到栈(stack)中,执行完毕后会释放堆或退出栈。执行完这个宏任务后,会判断微任务队列(microtask queue)是否为空,如果不为空,则会将所有的微任务依次取出并执行。如果在这个过程中触发了任何 Web APIs 将进行第二步操作。

第二步:调用 Web API,并在合适的时候将回调函数加入到事件回调队列(event queue)中。比如执行了setTimeout(callback1, 1000),会创建一个计时器,并且在另一个线程(浏览器定时触发线程)里面监听计时器是否过期,等到计时器过期后,会将对应回调 callback1加入事件回调队列中。

第三步:等到第一步中的微任务执行完毕之后,会判断事件回调队列(event queue)是否为空。如果不为空,则会取出并执行最先进入队列的回调函数,执行过程如同第一步。如果为空,则会视情况进行等待或挂起主线程。

补充说明:浏览器的内核是多线程的,常驻线程有浏览器 GUI 渲染线程、JavaScript 引擎线程、浏览器定时触发器线程、浏览器事件触发线程、浏览器 http 异步请求线程。

2.宏任务与微任务

宏任务(macrotask):script(整体代码)、setTimeout/setInterval、I/O、UI rendering等

微任务(microtask):Promise、MutationObserver等

JS代码执行过程——宏任务与微任务的执行示意图:

如图,可以看出JS执行过程中,是先执行一个宏任务,再执行这个宏任务产生的对应微任务,执行完毕后,再执行后面的宏任务,以此往复。

3.实例分析

使用浏览器:Chrome Version 80.0.3987.163

第一组:

比较 setTimeout 与 Promise

console.log('start')

setTimeout(() => {
console.log('setTimeout')
}, 0); Promise.resolve().then(() => {
console.log('microtask: promise')
}) console.log('end')

结果:

分析:

以JS的事件循环机制来分析。首先,script(整体代码)算是一个宏任务,执行完毕,会先后输出"start"和"end",然后执行这个过程中产生的微任务,即promis.then中的回调,输出"microtask: promise";这个过程中也调用了 Web API 中的 setTimeout,会创建一个计时器,过期后将回调添加到事件回调队列中;然后再执行回调(第二个宏任务),输出"setTimeout"。与浏览器运行输出一致,符合预期。

第二组:

宏任务与微任务的执行顺序对比

function func1() {
console.log('func1')
Promise.resolve().then(() => {
console.log('microtask.promise1')
})
} function func2() {
console.log('func2')
Promise.resolve().then(() => {
console.log('microtask.promise2')
})
} function main() {
func1()
func2()
setTimeout(func1, 0);
setTimeout(func2, 0);
} main()

结果:

分析:

从输出结果可以看出,当一个宏任务执行完毕后,会接着执行相应的所有微任务,执行完毕后,再执行后续的宏任务,并以往复,与预期相符。

4.参考

并发模型与事件循环

Javascript event loop

JavaScript Event Loop Explained

HTML系列:macrotask和microtask

【翻译】Promises/A+规范

最新文章

  1. Android实现播放器功能
  2. MySql数据库-使用cmd操作数据库
  3. Android Service 文档
  4. 关于EditText的一点深入的了解
  5. PMP--案例解答要点
  6. android API文档查询---context、toast、SharedPreferences
  7. web页面显示折叠树菜单笔记
  8. Linkedin工程师是如何优化他们的Java代码的(转)
  9. JSTL标签库---SUN公司开发的标签库
  10. asp.net core系列 45 Web应用 模型绑定和验证
  11. Java基础学习-关键字的概述和特点以及常量的概述和分类
  12. Mysql 存储过程批量建表
  13. 【XSY2534】【CF835D】Palindromic characteristics 回文自动机
  14. 转: MySQL5.7 ERROR 1142 (42000)问题
  15. Servlet的Cookie值保存与获取
  16. 对MVC模型的自悟,详尽解释,为了更多非计算机人员可以理解
  17. python learning OOP1.py
  18. 快速认识LinkIt 7697开发板
  19. vector 中的clear()
  20. springboot整合kafka应用

热门文章

  1. mysql两表合并,对一列数据进行处理
  2. Mybatis详解系列(一)--持久层框架解决了什么及如何使用Mybatis
  3. 李宏毅老师机器学习课程笔记_ML Lecture 3-1: Gradient Descent
  4. Python第五章-内置数据结构02-列表
  5. ReentrantLock源码解析——虽众但写
  6. 吴恩达最新TensorFlow专项课程开放注册,你离TF Boy只差这一步
  7. 干净直接安装+PS下载
  8. c++中的多态机制
  9. [noip模拟]难缠的值周生<宽搜>
  10. 原来rollup这么简单之 tree shaking篇