为何Promise回调晚于其他函数执行?MDN相关规则存疑
彻底搞懂Promise回调的执行顺序问题
哥们,你的这两个问题其实都指向同一个核心——JavaScript事件循环里同步任务、微任务的执行逻辑,咱们一步步拆解清楚,顺便纠正你对MDN那句话的理解偏差。
先纠正MDN那句话的正确含义
你看到的MDN原文:
Callbacks will never be called before the completion of the current run of the JavaScript event loop
这里的「current run」指的是当前同步执行栈里的所有代码全部执行完毕,而不是你理解的「resolve/reject之后的语句」。简单说:Promise的回调(then/catch/finally)属于「微任务」,它们必须等当前所有同步代码都跑完,才会有机会执行。
问题1:为什么自定义函数会在Promise回调之前执行?
举个你可能测试过的代码例子:
function myOtherFunction() { console.log("My Other Function"); } new Promise((resolve) => { // 这里的resolve是同步执行的 resolve("Success"); }).then((msg) => { // 这个回调会被放到微任务队列,不会立即执行 console.log(msg); }); // 这是同步任务,直接进入执行栈 myOtherFunction();
输出顺序必然是:
My Other Function Success
原因很简单:
- 执行同步代码:先创建Promise,同步执行resolve(只是标记Promise为已完成,把then回调塞进微任务队列)。
- 接着执行
myOtherFunction(),这是同步任务,直接在当前执行栈里运行,所以先输出"My Other Function"。 - 等当前所有同步代码都跑完了,执行栈空了,才会去遍历微任务队列,执行Promise的then回调,输出"Success"。
问题2:为什么Promise之后调用的函数,执行顺序也早于Promise回调?
这和第一个问题本质完全一样,还是同步任务优先于微任务的逻辑。哪怕你把自定义函数写在Promise代码的后面,它依然是同步任务,会在当前执行栈里先跑完,轮不到微任务队列里的Promise回调插队。
再举个例子:
new Promise((resolve) => { resolve("Success"); }).then((msg) => { console.log(msg); }); // 这个函数在Promise之后调用,但依然是同步任务 function myLateFunction() { console.log("My Late Function"); } myLateFunction();
输出顺序还是:
My Late Function Success
核心逻辑没变:同步任务全部执行完毕后,才会处理微任务队列。
给你梳理事件循环的简化执行流程
方便你彻底记住:
- 第一步:把当前所有同步代码塞进执行栈,依次执行,直到栈为空。
- 第二步:处理微任务队列(Promise回调、MutationObserver等),把队列里的所有微任务依次执行完毕,直到队列清空。
- 第三步:如果需要,浏览器会进行页面渲染。
- 第四步:处理宏任务队列(setTimeout、DOM事件、AJAX回调等),执行一个宏任务后,回到第二步重复流程。
Promise的回调属于微任务,所以优先级是:同步任务 > 微任务 > 宏任务。
内容的提问来源于stack exchange,提问作者AfterWorkGuinness
相关产品推荐
相关产品推荐

