返回
揭秘 JavaScript 事件循环的秘密:宏任务与微任务
前端
2023-10-16 23:25:05
在 JavaScript 的世界里,事件循环扮演着至关重要的角色,负责管理代码的执行顺序。它是一个单线程机制,一次只执行一个任务。然而,通过巧妙地利用宏任务和微任务,JavaScript 能够异步处理事件,从而创建响应迅速、高效的 Web 应用程序。
事件循环的概念
事件循环是一种循环机制,它不断检查是否存在等待执行的任务。当发现任务时,事件循环会将其从任务队列中取出并执行。任务队列是一个先进先出 (FIFO) 队列,这意味着最早添加的任务将首先被执行。
宏任务
宏任务是指需要较长时间才能完成的任务,例如 DOM 操作、网络请求和 setTimeout()。当事件循环发现宏任务时,它会将其添加到宏任务队列中。宏任务队列是另一个先进先出队列,这意味着宏任务将按照添加顺序依次执行。
微任务
微任务是指需要在当前事件循环中执行的任务,例如 Promise.then() 和 MutationObserver。当事件循环发现微任务时,它会将其添加到微任务队列中。微任务队列在每个宏任务执行完毕后被检查,这意味着微任务将在所有宏任务执行完毕后执行。
执行顺序
事件循环的执行顺序如下:
- 执行同步代码: 首先,事件循环将执行同步代码,即主线程中的所有代码。
- 执行微任务: 同步代码执行完毕后,事件循环将检查微任务队列并执行所有微任务。
- 执行宏任务: 微任务执行完毕后,事件循环将检查宏任务队列并执行所有宏任务。
- 检查事件队列: 宏任务执行完毕后,事件循环将检查事件队列,该队列包含来自外部事件(如鼠标点击或网络请求)的任务。如果有事件,事件循环将触发事件处理程序,并将其添加到任务队列中。
- 重复: 事件循环不断重复此过程,直到任务队列和事件队列都为空。
示例
让我们通过几个示例来理解事件循环的执行流程:
示例 1:
console.log("同步代码 1");
setTimeout(() => {
console.log("宏任务");
}, 0);
Promise.resolve().then(() => {
console.log("微任务");
});
console.log("同步代码 2");
执行顺序:
- 同步代码 1
- 同步代码 2
- 微任务
- 宏任务
示例 2:
console.log("同步代码 1");
setTimeout(() => {
console.log("宏任务 1");
setTimeout(() => {
console.log("宏任务 2");
}, 0);
}, 0);
Promise.resolve().then(() => {
console.log("微任务 1");
Promise.resolve().then(() => {
console.log("微任务 2");
});
});
console.log("同步代码 2");
执行顺序:
- 同步代码 1
- 同步代码 2
- 微任务 1
- 微任务 2
- 宏任务 1
- 宏任务 2
结论
JavaScript 的事件循环是一个强大的机制,它使我们能够在单线程环境中异步处理事件。通过理解宏任务和微任务的概念,我们可以优化我们的代码,创建响应迅速且高效的 Web 应用程序。掌握事件循环是任何 JavaScript 开发人员必备的技能。