JavaScript 事件循环

85 阅读2分钟

🌟 JavaScript 事件循环:让你彻底搞懂异步编程! 🌟

你是不是也曾被 JavaScript 的异步代码搞晕过?🤔
比如 setTimeoutPromiseasync/await,它们到底是怎么执行的?
今天就来揭秘 事件循环(Event Loop) 的奥秘,让你彻底掌握 JavaScript 的异步世界!🚀


1. 什么是事件循环?

JavaScript 是单线程的,但它却能处理异步任务,靠的就是 事件循环
事件循环是 JavaScript 运行时的一种机制,负责协调同步任务和异步任务的执行顺序。


2. 事件循环的核心:调用栈、任务队列、微任务队列

  • 调用栈(Call Stack)
    用来执行同步代码的地方,后进先出(LIFO)。
    (比如函数调用会压入栈,执行完会弹出。)
  • 任务队列(Task Queue)
    存放宏任务(Macro Task),比如 setTimeoutsetIntervalI/O 操作。
  • 微任务队列(Micro Task Queue)
    存放微任务(Micro Task),比如 Promise.thenMutationObserver

3. 事件循环的执行顺序

  1. 执行同步代码
    先执行调用栈中的同步任务,直到调用栈为空。
  2. 执行微任务
    检查微任务队列,依次执行所有微任务,直到微任务队列为空。
  3. 执行宏任务
    从任务队列中取出一个宏任务执行,然后回到第 2 步。
  4. 重复循环
    不断重复以上步骤,直到所有任务执行完毕。

4. 举个栗子 🌰

console.log('1'); // 同步任务

setTimeout(() => {
  console.log('2'); // 宏任务
}, 0);

Promise.resolve().then(() => {
  console.log('3'); // 微任务
});

console.log('4'); // 同步任务

输出顺序:
1432

解释:

  1. 先执行同步代码,输出 14
  2. 然后执行微任务队列中的 Promise.then,输出 3
  3. 最后执行宏任务队列中的 setTimeout,输出 2

5. 小贴士 💡

  • 微任务优先级高于宏任务
    微任务会在当前事件循环中立即执行,而宏任务需要等到下一个事件循环。
  • 避免阻塞事件循环
    如果同步代码执行时间过长,会导致页面卡顿,所以尽量将耗时操作放到异步任务中。
  • async/await 是 Promise 的语法糖
    await 后面的代码相当于 Promise.then,属于微任务。

6. 总结

  • 同步任务:直接执行。
  • 微任务:优先于宏任务执行。
  • 宏任务:最后执行。

掌握事件循环,就能轻松驾驭 JavaScript 的异步编程!🎉
赶紧试试吧,评论区告诉我你的理解!👇