一道关于事件循环(Event Loop) 机制和任务队列模型的面试题


​​代码示例​​

javascript 复制代码
console.log(1);
Promise.resolve().then(res => console.log(2));
setTimeout(() => console.log(3), 0);

​​执行顺序​​

​​输出结果:1 → 2 → 3​​


​​原理分析​​

1. ​​同步任务优先执行​​

  • ​console.log(1)​ 是同步任务,直接进入主线程执行,输出 1。
  • ​Promise.resolve()​ 的构造函数是同步执行的,但 .then() 的回调会被注册为微任务(Microtask)。

2. ​​微任务队列(Microtask Queue)​​

  • ​.then(res => console.log(2))​ 的回调被放入微任务队列。
  • ​微任务优先级高于宏任务​:在当前同步任务执行完毕后,事件循环会优先清空微任务队列。

3. ​​宏任务队列(Macrotask Queue)​​

  • ​setTimeout​ 的回调被放入宏任务队列。
  • 宏任务需等待当前所有微任务执行完毕后才会执行。

4. ​​事件循环流程​​

  1. ​​执行同步任务​ ​:输出 1。

  2. ​​注册微任务​ ​:将 .then 回调加入微任务队列。

  3. ​​注册宏任务​ ​:将 setTimeout 回调加入宏任务队列。

  4. ​​同步任务结束​​,开始处理微任务队列:

    • 执行 .then 回调,输出 2。
  5. ​​微任务队列清空​​,开始处理宏任务队列:

    • 执行 setTimeout 回调,输出 3。

​​关键概念​​

1. ​​任务队列分类​​

任务类型 示例 优先级
​​同步任务​​ console.log 最高
​​微任务​​ Promise.then 次高(当前轮次)
​​宏任务​​ setTimeout/setInterval 最低(下一轮次)

2. ​​事件循环核心规则​​

  • ​同步任务​:立即执行,阻塞后续代码。
  • ​微任务​ :在 ​当前宏任务结束后、下一个宏任务开始前​ 执行。
  • ​宏任务​:每次事件循环仅执行一个,由任务队列顺序决定。

​​浏览器与 Node.js 的差异​​

  • ​浏览器环境​:微任务在 DOM 渲染前执行。
  • ​Node.js​ :微任务在 process.nextTick 之后、setImmediate 之前执行。

​​复杂场景扩展​​

若代码改为:

javascript 复制代码
console.log(1);
setTimeout(() => {
  console.log(2);
  Promise.resolve().then(() => console.log(3));
}, 0);
Promise.resolve().then(() => console.log(4));

​​输出顺序:1 → 4 → 2 → 3​ ​

​​原因​​:

  1. 同步任务输出 1。
  2. 注册 setTimeout(宏任务)和 Promise.then(微任务)。
  3. 同步任务结束后,先执行微任务输出 4。
  4. 执行宏任务 setTimeout,输出 2,其回调中的 Promise.then 又注册一个微任务,输出 3。

​​总结​​

  • ​同步任务​:直接执行,无延迟。
  • ​微任务​:在当前事件循环末尾执行(如 Promise 回调)。
  • ​宏任务​:在下一次事件循环开始时执行(如 setTimeout)。

理解这一机制,能精准掌握异步代码的执行顺序,避免常见的回调地狱问题。

相关推荐
用户1197707948073几秒前
GitHub 电商开源项目分享:用 sharp 批量出饰品主图,试了裁剪、细节图和色彩配置文件三个坑
前端·node.js
deli0076 分钟前
地图定位为什么偏了 500 米?GPS 与火星坐标实测
前端
怕浪猫6 分钟前
我有个朋友,工作八年,公司从 300 人减到 80 人
面试·程序员
TK泰妞8 分钟前
节日促销前,TikTok 商品视频应该提前准备什么?
前端·人工智能·节日
CCIE-Yasuo19 分钟前
网络安全-学习web开发-列表、标签
前端·学习·web安全
小大宇23 分钟前
Vue知识点-ElementPlus-06 单选+多选+下拉+日期选择
前端·vue.js·elementui
考研保研资料分享23 分钟前
2024财会跨保北大金融科技:三场笔面试与经管法混申复盘
科技·面试·金融
用户114818678948425 分钟前
Nuxt 3 学习版 Demo:跟着做一遍,从跑起来到自己会改
前端
hiahiahia1231 小时前
Streaming Model Output
开发语言·前端
paopaokaka_luck1 小时前
基于springboot+vue的益暖微光公益服务平台(DeepSeek公益助手、善款信息追溯、志愿服务积分闭环、ECharts运营分析、活动状态自动流转)
java·前端·javascript·spring boot·mysql·架构·echarts