事件循环是 JavaScript 中一个核心的概念,它决定了 JavaScript 的执行顺序。以下是关于 JavaScript 事件循环的详细解释。

事件循环的基本概念

事件循环(Event Loop)是 JavaScript 运行时的一部分,它负责处理异步代码的执行。在事件循环中,JavaScript 引擎会不断地检查任务队列(Task Queue)和微任务队列(Microtask Queue),以及执行栈(Call Stack)。

执行栈

执行栈是 JavaScript 引擎执行代码的地方。当执行一个函数时,该函数会被推入执行栈中,直到函数执行完毕,它才会从执行栈中弹出。

function hello() {
  console.log('Hello, world!');
}

hello(); // 输出: Hello, world!

任务队列

任务队列(Task Queue)用于存储异步任务,例如 I/O 操作、定时器等。当异步任务完成时,它们会被推入任务队列。

微任务队列

微任务队列(Microtask Queue)用于存储比任务队列优先级更高的任务,例如 Promise 的回调函数。微任务队列会在每个事件循环的迭代中执行。

事件循环的流程

  1. 执行栈为空,检查微任务队列:

    • 如果微任务队列不为空,执行微任务队列中的所有任务。
    • 微任务队列清空。
  2. 执行栈为空,检查任务队列:

    • 如果任务队列不为空,将任务队列中的第一个任务推入执行栈。
    • 执行栈清空。
  3. 重复步骤 1 和步骤 2,直到执行栈和微任务队列为空。

示例

以下是一个简单的示例,展示了事件循环的流程:

console.log('1');

setTimeout(() => {
  console.log('2');
}, 0);

new Promise((resolve) => {
  console.log('3');
  resolve();
}).then(() => {
  console.log('4');
});

console.log('5');

// 输出: 1 3 5 4 2

在这个示例中,首先执行同步代码,输出 1 和 5。然后,将 setTimeoutPromise 的回调函数推入任务队列。在执行栈为空时,事件循环会检查微任务队列,发现 Promise 的回调函数,执行输出 3 和 4。最后,执行 setTimeout 的回调函数,输出 2。

扩展阅读

想要了解更多关于 JavaScript 事件循环的知识,可以阅读以下文章:

JavaScript 事件循环