JavaScript 的宏任务与微任务:深入理解异步执行机制

在 JavaScript 中,宏任务(MacroTask)和微任务(MicroTask)是实现异步编程的两个关键概念。本文将深入介绍这两个概念,解释它们的工作原理以及在实际开发中的应用。

1. 异步编程简介

在 JavaScript 中,由于单线程执行的特性,当执行到某个任务时,如果该任务需要等待一些操作(例如定时器、网络请求、事件监听等)完成,传统的同步执行方式会导致阻塞,用户界面无响应。因此,JavaScript 引入了异步编程的概念,允许某些任务在后台执行,不阻塞主线程。

2. 宏任务(MacroTask)

宏任务是由 JavaScript 引擎提供的任务队列中的一个个任务单元。每个宏任务都代表一个独立的、完整的执行单元。在宏任务队列中,任务按照顺序排列,每个任务之间互不干扰。典型的宏任务包括:

  • script(整体代码)
  • setTimeout
  • setInterval
  • I/O 操作
  • UI 渲染

宏任务的执行过程是先执行当前执行栈中的同步代码,然后从宏任务队列中取出一个任务执行,直到宏任务队列为空。

javascript 复制代码
console.log('Start');

setTimeout(function() {
  console.log('Timeout');
}, 0);

console.log('End');

上述代码中,setTimeout 的回调函数被放入宏任务队列,在主线程执行栈中的同步任务执行完毕后,才会执行宏任务队列中的任务。

3. 微任务(MicroTask)

微任务是相对于宏任务而言的,它的执行时机是在宏任务执行结束后、下一个宏任务开始前。微任务队列中的任务会在当前宏任务执行完毕后立即执行。典型的微任务包括:

  • Promise 的 then 方法
  • MutationObserver
  • process.nextTick(Node.js 环境)
javascript 复制代码
console.log('Start');

Promise.resolve().then(function() {
  console.log('Promise');
});

console.log('End');

在上述代码中,Promisethen 方法注册的回调函数是一个微任务,它会在当前宏任务执行结束后立即执行。

4. 执行顺序与例子

宏任务和微任务的执行顺序是有规律的:

  1. 当前执行栈执行完毕后,会立即检查微任务队列,如果有微任务,就按照先进先出的顺序依次执行。
  2. 微任务执行完毕后,如果有新的微任务加入,会继续执行,直到微任务队列为空。
  3. 然后,JavaScript 引擎会去宏任务队列中取出一个任务执行,执行完毕后重复步骤 1。

下面是一个例子:

javascript 复制代码
console.log('Start');

setTimeout(function() {
  console.log('Timeout');
}, 0);

Promise.resolve().then(function() {
  console.log('Promise');
});

console.log('End');

输出结果:

sql 复制代码
Start
End
Promise
Timeout

首先,同步代码执行,打印 StartEnd。然后,setTimeout 的回调和 Promisethen 回调都被放入对应的任务队列。微任务队列中的任务先执行,输出 Promise,然后宏任务队列中的任务执行,输出 Timeout

5. 应用场景

5.1 宏任务的应用

  • 定时器: 使用 setTimeoutsetInterval 可以创建宏任务,实现定时执行任务的效果。
javascript 复制代码
setTimeout(function() {
  console.log('Delayed task');
}, 1000);
  • I/O 操作: 从服务器获取数据、读写文件等操作都是宏任务。

5.2 微任务的应用

  • Promise: Promise 的 then 方法产生的回调是微任务,可以在异步操作完成后执行。
javascript 复制代码
Promise.resolve().then(function() {
  console.log('Promise task');
});
  • MutationObserver: 监听 DOM 变化的回调是微任务。
javascript 复制代码
var observer = new MutationObserver(function() {
  console.log('DOM changed');
});

observer.observe(document.body, { attributes: true });
document.body.setAttribute('class', 'new-class');

6. 总结

宏任务和微任务是 JavaScript 中实现异步编程的两个重要概念。了解它们的执行时机和应用场景有助于更好地理解 JavaScript 的事件循环机制,提高异步编程的效率。在实际应用中,宏任务和微任务的合理使用能够优化代码执行顺序,提升用户体验。

相关推荐
IT古董6 分钟前
全面理解 Corepack:Node.js 的包管理新时代
前端·node.js·corepack
Jonathan Star7 分钟前
NestJS 是基于 Node.js 的渐进式后端框架,核心特点包括 **依赖注入、模块化架构、装饰器驱动、TypeScript 优先、与主流工具集成** 等
开发语言·javascript·node.js
学习3人组10 分钟前
清晰地说明 NVM、NPM 和 NRM 在 Node.js 开发过程中的作用
前端·npm·node.js
矢心18 分钟前
setTimeout 和 setInterval:看似简单,但你不知道的使用误区
前端·javascript·面试
一枚前端小能手34 分钟前
🧭 使用历史记录 API - SPA导航与状态管理的完整指南
前端·javascript
用户479492835691537 分钟前
从字符串满天飞到优雅枚举:JavaScript 常量管理的几种姿势
前端·javascript
qq_4152162538 分钟前
Vue3+vant4+Webpack+yarn项目创建+vant4使用注意明细
前端·webpack·node.js
李建军1 小时前
ASP.NET Core Web 应用SQLite数据连接显示(1)
前端
耀耀切克闹灬1 小时前
word文档转html(mammoth )
前端
文心快码BaiduComate1 小时前
双十一将至,用Rules玩转电商场景提效
前端·人工智能·后端