返回
揭秘 JavaScript 宏任务和微任务,深入理解事件循环
前端
2024-02-09 04:17:48
宏任务与微任务
在 JavaScript 中,所有的任务都分为两大类:宏任务和微任务。宏任务包括:
- script :脚本代码,即浏览器加载的 JavaScript 文件。
- setTimeout() :定时器函数,用于在指定时间后执行回调函数。
- setInterval() :定时器函数,用于每隔一段时间执行回调函数。
- setImmediate() :立即执行函数,用于在当前事件循环的末尾执行回调函数。
- requestAnimationFrame() :动画帧请求函数,用于在浏览器下一次重绘之前执行回调函数。
微任务包括:
- Promise.then() :Promise 对象的 then() 方法,用于在 Promise 对象状态改变后执行回调函数。
- Promise.catch() :Promise 对象的 catch() 方法,用于在 Promise 对象状态变为 rejected 后执行回调函数。
- Promise.finally() :Promise 对象的 finally() 方法,用于在 Promise 对象状态改变后(无论状态如何)执行回调函数。
- MutationObserver :MutationObserver 对象,用于观察 DOM 树的变化,并在变化发生后执行回调函数。
- MessageChannel :MessageChannel 对象,用于在不同的线程之间传递消息,并在消息被接收后执行回调函数。
事件循环
事件循环是 JavaScript 引擎处理任务的机制。它是一个不断循环的过程,主要分为以下几个步骤:
- 执行同步任务:在事件循环的每个阶段,首先会执行同步任务,即主线程上的任务。
- 执行微任务:在同步任务执行完毕后,会执行微任务。微任务的执行顺序与它们的创建顺序一致。
- 更新渲染树:在微任务执行完毕后,浏览器会更新渲染树,即根据 DOM 树和 CSS 样式表生成新的页面。
- 执行宏任务:在渲染树更新完毕后,会执行宏任务。宏任务的执行顺序与它们的创建顺序一致。
执行时机
在事件循环中,宏任务和微任务的执行时机如下:
- 宏任务 :宏任务会在当前事件循环的末尾执行,即在所有微任务执行完毕后。
- 微任务 :微任务会在当前事件循环的每个阶段执行,即在同步任务执行完毕后,在宏任务执行之前。
应用场景
宏任务和微任务在实际开发中有着广泛的应用场景,例如:
- 延迟任务执行 :可以使用 setTimeout() 或 setInterval() 函数来延迟任务的执行。例如,可以在页面加载完成后,使用 setTimeout() 函数延迟执行一个函数来初始化页面。
- 动画 :可以使用 requestAnimationFrame() 函数来创建动画效果。requestAnimationFrame() 函数会确保动画在浏览器下一次重绘之前执行,从而实现流畅的动画效果。
- 异步编程 :可以使用 Promise 对象来实现异步编程。Promise 对象可以表示一个异步操作的结果,并允许你对结果进行处理。例如,可以在发送 AJAX 请求后,使用 Promise 对象来等待请求结果,并在结果返回后执行回调函数。
- DOM 操作 :可以使用 MutationObserver 对象来观察 DOM 树的变化。MutationObserver 对象可以在 DOM 树发生变化后执行回调函数,从而实现对 DOM 树的动态更新。
- 消息传递 :可以使用 MessageChannel 对象在不同的线程之间传递消息。MessageChannel 对象可以创建两个端口,一个端口用于发送消息,另一个端口用于接收消息。当消息被接收后,会执行回调函数。
结论
宏任务和微任务是 JavaScript 中两个重要的概念,它们决定了异步代码的执行顺序。宏任务包括 script、setTimeout()、setInterval()、setImmediate() 和 requestAnimationFrame(),而微任务包括 Promise.then()、Promise.catch()、Promise.finally()、MutationObserver 和 MessageChannel。宏任务会在当前事件循环的末尾执行,即在所有微任务执行完毕后,而微任务会在当前事件循环的每个阶段执行,即在同步任务执行完毕后,在宏任务执行之前。宏任务和微任务在实际开发中有着广泛的应用场景,例如延迟任务执行、动画、异步编程、DOM 操作和消息传递。