14、✅ 手写 Event Loop 模拟器(理解微任务 / 宏任务调度)

🎯 一、为什么要手写 Event Loop?

  • 大厂面试必问:async/await、Promise、setTimeout 混合输出顺序
  • 源码能力提升:搞懂浏览器/Node.js 的任务调度机制
  • 理解 JS 单线程异步执行本质,为后续自己写任务队列打下基础

🧠 二、Event Loop 核心概念速查

术语 解释
Call Stack 调用栈,JS 执行同步任务的地方
Macro Task 宏任务,如 setTimeout/setInterval/I/O
Micro Task 微任务,如 Promise.then/MutationObserver
Event Loop 事件循环,调度所有任务的"引擎"
  • 执行顺序:主线程同步任务 → 微任务队列 → 宏任务队列
  • 每次执行完一个宏任务后,立即清空所有微任务

🔍 三、常考面试题(输出顺序)

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

输出顺序? 1、4、3、2


✍️ 四、核心思想:模拟微/宏任务队列

  1. 维护两个队列:macroQueuemicroQueue
  2. 每次执行一个 macro 后,依次执行 microQueue 直到清空
  3. 采用递归或循环驱动任务调度

📦 五、简易 Event Loop 模拟器实现

kotlin 复制代码
class EventLoop {
  constructor() {
    this.macroQueue = [];
    this.microQueue = [];
    this.running = false;
  }

  // 加入宏任务
  setMacroTask(fn) {
    this.macroQueue.push(fn);
    this.run();
  }

  // 加入微任务
  setMicroTask(fn) {
    this.microQueue.push(fn);
    this.run();
  }

  run() {
    if (this.running) return;
    this.running = true;

    while (this.macroQueue.length > 0) {
      // 执行一个宏任务
      const macro = this.macroQueue.shift();
      macro();

      // 清空微任务队列
      while (this.microQueue.length > 0) {
        const micro = this.microQueue.shift();
        micro();
      }
    }

    this.running = false;
  }
}

✅ 六、使用示例(验证调度顺序)

arduino 复制代码
const loop = new EventLoop();

console.log(1);

loop.setMacroTask(() => {
  console.log(2);
});

loop.setMicroTask(() => {
  console.log(3);
});

console.log(4);

// 输出:1 4 3 2

🔁 七、进阶模拟 async/await

async/await 本质就是自动拆分为同步 + 微任务

javascript 复制代码
async function test() {
  console.log('a');
  await Promise.resolve();
  console.log('b');
}
test();
console.log('c');
// 输出:a c b
  • await 前为同步,await 后回到微任务

❗ 八、面试陷阱总结

题型 易错点
setTimeout + Promise 谁先输出? Promise 微任务先于 setTimeout 宏任务
多重微任务 一次性全部执行,直到清空 microQueue
多层嵌套 推理需模拟"每次大循环后立即清 micro"
相关推荐
没逛够8 分钟前
Vue 自适应高度表格
javascript·vue.js·elementui
太过平凡的小蚂蚁2 小时前
Kotlin 协程中常见的异步返回与控制方式(速览)
开发语言·前端·kotlin
咖啡の猫2 小时前
Vue初始化脚手架
前端·javascript·vue.js
晨枫阳3 小时前
uniapp兼容问题处理总结
前端·vue.js·uni-app
liusheng4 小时前
腾讯地图 SDK 接入到 uniapp 的多端解决方案
前端·uni-app
拉不动的猪4 小时前
如何处理管理系统中(Vue PC + uni-app 移动端):业务逻辑复用基本方案
前端·javascript·架构
边洛洛4 小时前
next.js项目部署流程
开发语言·前端·javascript
Zsnoin能4 小时前
浏览器连接 新北洋BTP-P33/P32蓝牙打印机,打印 二维码
前端
非凡ghost4 小时前
Syncovery Premium(文件同步软件)
前端·javascript·后端
trsoliu4 小时前
2025前端AI Coding产品与实战案例大盘点
前端·ai编程