事件循环

97 阅读1分钟

基本流程

  1. 调用栈(Call Stack) :调用栈是一个存放函数调用的栈结构。JavaScript 引擎会按顺序执行栈中的同步代码。
  2. 任务队列(Task Queue) :当遇到异步任务(例如 setTimeoutPromise 等)时,这些任务不会立即执行,而是加入到任务队列中。
  3. 事件循环(Event Loop) :事件循环不断地检查调用栈是否为空。当栈为空时,事件循环会将任务队列中的任务放入调用栈中执行。这就使得异步任务能够在同步代码执行完毕后被执行。

任务类型

  • 宏任务(Macro Task) :如 setTimeoutsetInterval、I/O 任务等。每次事件循环执行时,宏任务队列中只会取一个任务放入调用栈执行。
  • 微任务(Micro Task) :如 Promise.thenMutationObserver 等。在宏任务执行完毕之后,事件循环会清空微任务队列中所有的任务。

执行顺序示例

javascript
复制代码
console.log("1"); // 同步代码,立即执行

setTimeout(() => {
  console.log("2"); // 宏任务,延迟执行
}, 0);

Promise.resolve().then(() => {
  console.log("3"); // 微任务,延迟执行,但优先级高于宏任务
});

console.log("4"); // 同步代码,立即执行

输出顺序为:1 -> 4 -> 3 -> 2

原因解析

  1. 14 是同步代码,立即执行。
  2. Promise.then 回调是微任务,在同步代码完成后立即执行。
  3. setTimeout 是宏任务,会被放入下一轮事件循环。