宏任务与微任务决定执行顺序:同步代码先执行,宏任务如setTimeout后于微任务如Promise.then执行。事件循环每次执行一个宏任务后立即清空微任务队列。例如,Promise初始化和then回调中,同步输出“Promise初始化”,接着“同步代码结束”,之后处理微任务输出“Promise then执行”,最后执行下一个宏任务“setTimeout执行”。即使在setTimeout内创建Promise,其then仍作为微任务在该宏任务结束后立即执行,而非等待下一宏任务。async/await也基于微任务机制,await后的代码被包装成Promise.then,延迟到微任务阶段执行。因此,正确理解宏任务与微任务的优先级和执行时机是掌握JavaScript异步行为的关键。

在 JavaScript 中,异步编程离不开事件循环(Event Loop)机制,而微任务队列是其中的关键部分。很多人对 Promise 和 setTimeout 的执行顺序感到困惑,其实只要理解了宏任务与微任务的区别,这个问题就迎刃而解。
宏任务与微任务的基本概念
JavaScript 的任务分为两类:
宏任务(Macrotask):包括整体代码块、setTimeout、setInterval、I/O、UI 渲染等。 微任务(Microtask):包括 Promise.then/catch/finally、MutationObserver、queueMicrotask 等。
事件循环每次从宏任务队列中取出一个任务执行,执行完毕后,会清空当前所有的微任务队列,然后再取下一个宏任务。
Promise 是微任务,setTimeout 是宏任务
这是理解执行顺序的核心。来看一个经典例子:
立即学习“Java免费学习笔记(深入)”;
let promise = new Promise(resolve => { console.log(‘Promise 初始化’); resolve();});promise.then(() => { console.log(‘Promise then 执行’);});setTimeout(() => { console.log(‘setTimeout 执行’);}, 0);console.log(‘同步代码结束’);
输出结果为:
Promise 初始化 同步代码结束 Promise then 执行 setTimeout 执行
说明:
“Promise 初始化” 是同步执行的。 “同步代码结束” 紧随其后。 此时当前宏任务结束,开始处理微任务队列,执行 .then 回调。 微任务清空后,进入下一个宏任务,执行 setTimeout 回调。
微任务在宏任务之间被集中执行
即使在 setTimeout 回调中创建 Promise,它的 .then 也会在该宏任务结束后立即执行:
setTimeout(() => { console.log(‘宏任务:setTimeout’); Promise.resolve().then(() => { console.log(‘微任务:setTimeout 内部的 Promise’); });}, 0);Promise.resolve().then(() => { console.log(‘微任务:外部 Promise’);});console.log(‘主流程结束’);
输出:
主流程结束 微任务:外部 Promise 宏任务:setTimeout 微任务:setTimeout 内部的 Promise
解释:
主流程是一个宏任务,执行完后先处理微任务队列,输出“外部 Promise”。 然后进入下一个宏任务(setTimeout),输出“宏任务:setTimeout”。 该宏任务执行完后,再检查是否有微任务——发现内部 Promise 的回调,于是执行它。
常见误区与注意事项
有些人认为 setTimeout(fn, 0) 就能立刻执行,但实际上它只是将任务推入下一个宏任务队列,必须等待所有微任务完成。
另一个误区是认为 async/await 不产生微任务。实际上,async 函数中的 await 后续代码会被包装成 Promise.then,也就是微任务。
async function async1() { console.log(‘async1 开始’); await async2(); console.log(‘async1 结束’);}async function async2() { console.log(‘async2’);}async1();console.log(‘同步代码’);
输出:
async1 开始 async2 同步代码 async1 结束
因为 await 相当于把“async1 结束”放进微任务队列,等当前宏任务结束后才执行。
基本上就这些。掌握微任务和宏任务的执行节奏,就能准确预测 JavaScript 异步代码的行为。不复杂但容易忽略。
以上就是JavaScript 微任务队列:理解 Promise 与 setTimeout 的执行顺序的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1535384.html
微信扫一扫
支付宝扫一扫