JavaScript中宏任务队列的执行顺序是什么

来源:AI编程作者:唐僧头衔:草根站长
导读:本期聚焦于小伙伴创作的《JavaScript中宏任务队列的执行顺序是什么》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《JavaScript中宏任务队列的执行顺序是什么》有用,将其分享出去将是对创作者最好的鼓励。

JavaScript是单线程语言,所有任务都需要按顺序执行,为了处理异步操作,引入了事件循环和任务队列的概念,宏任务队列就是其中一类重要的任务队列,它的执行顺序遵循特定的规则。

JavaScript中宏任务队列的执行顺序是什么

宏任务的基本概念

宏任务指的是由宿主环境(如浏览器、Node.js)发起的异步任务,常见的宏任务类型包括setTimeoutsetIntervalsetImmediate(Node.js环境)、requestAnimationFrame(浏览器环境)、I/O操作、UI渲染等。

每个宏任务执行完成后,会检查是否存在微任务,所有微任务执行完毕之后,才会执行下一个宏任务,这是事件循环的核心逻辑之一。

宏任务队列的执行顺序规则

宏任务队列的执行顺序遵循以下核心规则:

  • 首先执行当前主线程的同步代码,同步代码属于第一个宏任务的一部分。
  • 同步代码执行完成后,从宏任务队列中取出最早进入队列的宏任务执行。
  • 单个宏任务执行完成后,会立即执行当前所有待执行的微任务,直到微任务队列清空。
  • 微任务执行完毕后,再取出下一个最早进入宏任务队列的任务执行,重复上述流程。

代码示例演示执行顺序

下面通过一个浏览器环境的代码示例,直观展示宏任务队列的执行顺序:

// 同步代码,属于第一个宏任务
console.log('同步代码1');

// setTimeout是宏任务,延迟0毫秒,会被加入宏任务队列
setTimeout(() => {
    console.log('setTimeout1回调');
    // 回调内部的Promise.then是微任务
    Promise.resolve().then(() => {
        console.log('setTimeout1内的微任务');
    });
}, 0);

// 另一个setTimeout宏任务
setTimeout(() => {
    console.log('setTimeout2回调');
}, 0);

// 同步代码
console.log('同步代码2');

// 主线程同步代码执行完成后,执行微任务队列中的任务
Promise.resolve().then(() => {
    console.log('同步后的微任务1');
});

Promise.resolve().then(() => {
    console.log('同步后的微任务2');
});

上述代码的执行结果依次为:

  • 同步代码1
  • 同步代码2
  • 同步后的微任务1
  • 同步后的微任务2
  • setTimeout1回调
  • setTimeout1内的微任务
  • setTimeout2回调

可以看到,两个setTimeout的回调按照进入宏任务队列的顺序依次执行,每个宏任务执行后都会先清空微任务队列,再执行下一个宏任务。

不同宏任务类型的入队顺序影响

如果不同类型的宏任务同时被触发,进入队列的顺序会影响执行顺序,比如浏览器中requestAnimationFramesetTimeout的执行顺序:

// requestAnimationFrame是浏览器宏任务,在下一帧渲染前执行
requestAnimationFrame(() => {
    console.log('requestAnimationFrame回调');
});

// setTimeout延迟0毫秒
setTimeout(() => {
    console.log('setTimeout回调');
}, 0);

在浏览器环境中,requestAnimationFrame的回调会在setTimeout回调之前执行,因为requestAnimationFrame的触发时机早于setTimeout的入队时机,所以会先进入宏任务队列,先被执行。

常见误区说明

很多开发者会误以为setTimeout的延迟时间到了就会立即执行,实际上延迟时间只是任务被加入宏任务队列的最早时间,如果此时主线程或者前面的宏任务、微任务还在执行,该setTimeout回调就需要等待前面的任务执行完成才能运行。

比如在下面的例子中,setTimeout的延迟是0毫秒,但因为主线程有耗时操作,回调会被推迟执行:

console.log('开始');

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

// 模拟耗时100毫秒的同步操作
const start = Date.now();
while (Date.now() - start < 100) {}

console.log('结束');

执行结果是先输出开始、结束,再输出setTimeout回调,因为耗时同步操作占用了主线程,导致setTimeout回调只能等同步操作完成后才能进入执行流程。

总结

JavaScript中宏任务队列的执行顺序核心是先进先出,同时遵循事件循环的规则:单个宏任务执行完成后必须清空所有微任务,再执行下一个宏任务。不同类型的宏任务入队时机不同,会影响最终的执行顺序,开发者需要结合具体的宏任务类型和入队时间判断执行顺序,避免异步代码的逻辑错误。

JavaScript宏任务队列事件循环setTimeout任务调度修改时间:2026-07-12 15:21:26

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。