You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么`after resolve`的执行顺序早于`after wait`?

JavaScript微任务队列执行顺序的误区解析

问题背景

我编写了一段JavaScript代码,运行后实际输出中after resolve早于after wait执行,但我原本以为after wait会更早被推入微任务队列并先执行,想知道这个认知存在什么误区。

原始代码

console.log('test')

async function async1() {
    console.log('before wait');
    await wait();
    console.log('after wait');
}

async function wait() {
    try {
        return await new Promise((res, rej) => {
            console.log('wait');
            rej('reject');
        });
    } catch (reason) {
        console.log(reason);
    }
}

async function test() {
    async1();
    console.log('before resolve');
    await Promise.resolve();
    console.log('after resolve');
}

test();

console.log('test end');

实际输出

[LOG]: "test" 
[LOG]: "before wait" 
[LOG]: "wait" 
[LOG]: "before resolve" 
[LOG]: "test end" 
[LOG]: "reject" 
[LOG]: "after resolve" 
[LOG]: "after wait" 

改写后的代码(替换async/await为then)

console.log('test')

function async1() {
    console.log('before wait');
    return wait().then(() => {
        console.log('after wait');
    })
}

function wait() {
    return new Promise((res, rej) => {
        console.log('wait');
        rej('reject');
    }).catch((reason) => {
        console.log(reason);
    })
}

function test() {
    async1();
    console.log('before resolve');
    Promise.resolve().then(() => {
        console.log('after resolve');
    })
}

test();

console.log('test end');

核心误区解析

你的错误认知在于误以为async1中await wait()的后续代码会比test中await Promise.resolve()的后续代码更早进入微任务队列,但实际执行流程中两者的入队时间有先后差,具体拆解如下:

1. 同步代码执行阶段

  • 先执行全局同步代码:打印test,调用test()函数
  • 进入test():
    • 调用async1(),打印before wait后调用wait()
    • 进入wait():创建Promise并执行executor,打印wait后直接reject,此时这个Promise变为rejected状态;await这个rejected Promise会暂停wait()的执行,将catch块的逻辑(打印reason)放入微任务队列,同时wait()返回一个pending状态的Promise给async1的await
    • 回到test(),继续执行同步代码:打印before resolve,然后await Promise.resolve()会将console.log('after resolve')放入微任务队列,test()返回pending Promise
  • 最后执行全局同步代码:打印test end

此时微任务队列的顺序是:

  • 第一顺位:wait()中处理reject的catch块(打印reject)
  • 第二顺位:test()中await Promise.resolve()后的console.log('after resolve')

2. 微任务处理阶段

  • 先执行第一顺位微任务:打印reject,此时wait()的catch执行完毕,wait()返回的Promise变为resolved状态
  • 只有当wait()的Promise变为resolved后,async1中的await wait()才会完成,将console.log('after wait')加入微任务队列
  • 接着执行第二顺位微任务:打印after resolve
  • 最后执行新加入的微任务:打印after wait

简单来说,wait()返回的Promise并非立即resolved,它需要等内部的catch微任务执行完毕才会切换状态,这直接导致async1中await的后续代码入队时间晚于test中await Promise.resolve()的后续代码,最终出现after resolve先执行的结果。

内容的提问来源于stack exchange,提问作者YJ Cai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 06:20:08