深入理解 JavaScript 执行机制:事件循环、执行栈、同步与异步彻底搞懂

深入理解 JavaScript 执行机制:事件循环、执行栈、同步与异步彻底搞懂

很多前端开发者在学习 JavaScript 时,都会遇到一个问题:

为什么 JavaScript 是单线程,却能处理异步任务?

为什么 Promise 比 setTimeout 先执行?

为什么代码执行顺序总是和写的顺序不一样?

要彻底理解这些问题,就必须搞清楚 JavaScript 的执行机制。

本文将系统讲清:

  • 同步任务
  • 异步任务
  • 执行栈
  • Web API
  • 任务队列
  • 宏任务与微任务
  • 事件循环(Event Loop)

并通过执行流程一步一步拆解运行原理。


一、JavaScript 为什么需要执行机制?

JavaScript 是单线程语言。

也就是说:

同一时间只能执行一件事。

如果没有异步机制,浏览器将无法处理:

  • 用户点击
  • 网络请求
  • 定时任务
  • 页面渲染

整个页面会被阻塞。

因此浏览器设计了一套协作机制:

执行栈 + Web API + 任务队列 + 事件循环

让单线程也能处理异步。


二、同步任务与异步任务

1 同步任务

同步任务会立即执行,按顺序进入执行栈。

示例:

arduino 复制代码
console.log(1)
console.log(2)
console.log(3)

执行顺序严格一致:

复制代码
1 2 3

同步代码执行期间,后面的代码必须等待。


2 异步任务

异步任务不会立即执行,而是交给浏览器处理。

常见异步操作:

  • setTimeout
  • 网络请求
  • DOM 事件
  • Promise

当异步任务完成后,不会立刻执行,而是进入任务队列等待。


三、执行栈(Call Stack)

执行栈用于存放当前正在执行的函数。

执行规则:

后进先出(LIFO)。

函数调用时入栈,执行完成后出栈。

示例:

scss 复制代码
function a(){ b() }
function b(){ c() }
function c(){ console.log("end") }
a()

执行顺序:

css 复制代码
a → b → c → 执行 → 返回

四、Web API 的作用

JavaScript 本身没有定时器、DOM、Ajax。

这些都是浏览器提供的能力。

当执行:

scss 复制代码
setTimeout(fn, 1000)

流程:

1 JS 交给浏览器 Web API

2 浏览器计时

3 时间到后,把回调函数放入任务队列


五、任务队列(Task Queue)

任务队列用于存放异步任务的回调函数。

执行条件:

只有执行栈清空,任务队列才会被取出执行。


六、宏任务与微任务(重点)

任务队列分两种。

宏任务

  • setTimeout
  • setInterval
  • DOM事件
  • Ajax

微任务

优先级更高:

  • Promise.then
  • MutationObserver
  • queueMicrotask

执行顺序:

复制代码
同步代码
↓
执行所有微任务
↓
执行一个宏任务
↓
再执行微任务
↓
循环

七、事件循环(Event Loop)

事件循环是 JavaScript 的调度中心。

工作逻辑:

不断检查执行栈。

如果执行栈为空:

1 先执行微任务队列

2 再执行宏任务队列

不断重复。


八、完整执行流程示例

javascript 复制代码
console.log(1)

setTimeout(()=>{
  console.log(2)
})

Promise.resolve().then(()=>{
  console.log(3)
})

console.log(4)

执行顺序:

1 同步执行 → 1 4

2 执行微任务 → 3

3 执行宏任务 → 2

最终输出:

复制代码
1 4 3 2

九、执行机制整体流程总结

JavaScript 运行流程:

1 执行同步代码进入执行栈

2 遇到异步任务交给 Web API

3 异步完成进入任务队列

4 执行栈清空后

5 事件循环调度任务执行

6 无限循环


十、一句话总结

JavaScript 通过:

执行栈 + Web API + 任务队列 + 事件循环

实现了单线程异步执行模型。

理解事件循环,本质就是理解:

代码什么时候进入执行栈。


如果这篇文章对你有帮助,欢迎点赞收藏。

相关推荐
To_OC1 小时前
别再串行写 await 了,Promise.all 才是并行请求的正确打开方式
前端·javascript·promise
To_OC1 小时前
LC 17 电话号码的字母组合:我的回溯算法,就是从这道题开窍的
javascript·算法·leetcode
vipbic1 小时前
中后台越做越乱后,我用插件化把它救回来了
前端·vue.js
Hyyy1 小时前
Computer Use 适合做什么,不适合做什么——一次真实使用后的思考
前端
小和尚同志2 小时前
前端 AI 单元测试思考与落地
前端·人工智能·aigc
invicinble3 小时前
c端系统,其实更像一个信息展示平台
前端
你怎么知道我是队长3 小时前
JavaScript的变量和数据类型介绍
开发语言·javascript·ecmascript
李姆斯4 小时前
管理是否可以被完全量化
前端·产品经理·团队管理
名字还没想好☜4 小时前
Next.js 中间件实战:鉴权、重定向与 A/B 分流
开发语言·前端·javascript·中间件·react·next.js
广州灵眸科技有限公司5 小时前
瑞芯微RV1126B开发板(EASY-EAI-PI2) INI文件操作
java·前端·javascript·网络·人工智能