理解JS事件环(Event Loop)

事件环(Event Loop)

任务分类

  • 宏任务

    • 脚本执行(顺序执行)
    • UI 渲染
    • 定时器(setTimeout)
    • HTTP 请求
    • 事件处理
    • MessageChannel
    • setImmediate
  • 微任务

    • Promise.then
    • MutationObserver
    • process.nextTick
    • queueMicrotask

执行顺序

  1. 执行一个宏任务
  2. 清空微任务队列
  3. 重复步骤 1 和 2

微任务与宏任务执行顺序示例

javascript 复制代码
console.log(1);
async function async() {
  console.log(2);
  await console.log(3); // 相当于 Promise.resolve(console.log(3)).then(()=>{console.log(4)})
  console.log(4); // 也会产生一个 then,在之后执行
}
setTimeout(() => {
  console.log(5);
}, 0);
const promise = new Promise((resolve, reject) => {
  console.log(6);
  resolve(7);
});
promise.then((res) => {
  console.log(res);
});
async();
console.log(8);

执行顺序分析

  1. 同步代码执行

    • console.log(1) → 输出 1
    • console.log(6) → 输出 6(Promise 构造函数中的同步代码)
    • console.log(2) → 输出 2(async 函数开始执行)
    • console.log(3) → 输出 3(await 后面的同步代码)
    • console.log(8) → 输出 8
  2. 微任务队列

    • Promise.then 回调(输出 7)
    • async 函数中 await 后的代码(输出 4)
  3. 宏任务队列

    • setTimeout 回调(输出 5)

最终输出顺序

复制代码
1
6
2
3
8
7
4
5

执行过程详解

  1. 首先执行所有同步代码(1, 6, 2, 3, 8)
  2. 然后清空微任务队列:
    • 执行 Promise.then 回调(7)
    • 执行 async 函数中 await 后的代码(4)
  3. 最后执行宏任务队列中的 setTimeout 回调(5)

关键点说明

  • async/await 本质上是 Promise 的语法糖
  • await 后面的代码会被包装成 Promise.then 回调
  • 微任务优先于宏任务执行
  • 同步代码优先于异步代码执行
  • Promise 构造函数中的代码是同步执行的
  • setTimeout 是宏任务,即使延迟时间为 0

其他重要概念

  • requestAnimationFrame:用于优化动画
  • requestIdleCallback:用于空闲时间任务调度
  • 进程间通信(IPC):多进程间通信机制
相关推荐
梨子同志几秒前
Monorepo
前端
lihaozecq2 分钟前
继 Web Coding Agent 后,我做了一个本地优先的桌面 AI Agent
前端·agent
用户298698530149 分钟前
在 React 中使用 JavaScript 将 Excel 转换为 SVG
前端·javascript·react.js
CodingSpace21 分钟前
ESLint
前端
Csvn29 分钟前
异步错误捕获的六大陷阱:await 裹着 try-catch 就一定稳了吗?
前端
用户0595401744632 分钟前
向量库静默丢数据踩坑实录:Playwright 端到端测试让我排查了72小时
前端·css
星栈37 分钟前
SPA 写累了?试试 LiveView:服务端管状态,前端不写 JS
前端·前端框架·elixir
labixiong40 分钟前
手写Promise--微任务、静态方法、async/await 全搞懂(三)
前端·javascript
Asize1 小时前
CSS 3D:从布局到立方体
前端
梨子同志1 小时前
React
前端