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

JavaScript中await未按预期等待后续代码执行的原因排查

JavaScript异步执行顺序问题排查与解决

我正在学习JavaScript异步操作,编写了以下代码:

async function cout_after10(num) {
    setTimeout(() => {
        console.log(num)
    }, 10)
};

async function cout_after0(num) {
    setTimeout(() => {
        console.log(num)
    }, 0)
};

// 主函数
(async function () {
    async function test() {
        await console.log(1)
        console.log(3)
        setTimeout(() => console.log(7), 5)
        console.log(4)
    }
    test()
    console.log(2)
    await cout_after10(8)
    await cout_after0(6)
    console.log(5)
})();

输出差异问题

我预期的输出是:

1, 2, 3, 4, 5, 7, 8, 6

但实际输出是数字升序,最后三位和预期完全不符。

我对执行顺序的理解

  1. 同步执行test(),进入test作用域,打印1,将后续代码放入微任务队列。
  2. 打印2。
  3. 执行cout_after10(8),因为是异步函数,将其放入宏任务队列;await会阻塞后续代码,直到该函数完成,同时把后续代码放入微任务队列。
  4. 同步代码执行完毕,从微任务队列取出任务执行:打印3,将setTimeout(() => console.log(7), 5)放入宏任务队列,然后打印4。
  5. 执行微任务队列中await cout_after10(8)后的代码:将cout_after0(6)放入宏任务队列,把console.log(5)放入微任务队列。
  6. 微任务队列仅剩console.log(5),执行并打印5。

核心困惑

后续宏任务的执行顺序完全超出预期:
7. 我认为宏任务队列会按插入顺序执行以下任务:

setTimeout(() => console.log(7), 5);
cout_after10(8);
cout_after0(6);

理论上应该打印7、8、6,但实际是按延迟时间从短到长的顺序打印6、7、8。

另外,我原本以为await会保证顺序执行:

await cout_after10(8);
await cout_after0(6);

应该先打印8再打印6,但实际并非如此,await没有起到预期的阻塞作用。


问题根源与修正方案

问题出在异步函数没有返回Promise。async函数如果没有显式返回Promise,会默认返回一个已resolved的Promise,导致await不会等待内部的setTimeout完成。修改代码让函数返回Promise后,即可按预期顺序执行:

async function cout_after10(num) {
    return new Promise((resolve) => {
        setTimeout(() => {
            console.log(num)
            resolve(0)
        }, 10)
    })
};

async function cout_after0(num) {
    return new Promise((resolve) => {
        setTimeout(() => {
            console.log(num)
            resolve(0)
        }, 0)
    })
};

// 主函数
(async function () {
    async function test() {
        await console.log(1)
        console.log(3)
        setTimeout(() => console.log(7), 5)
        console.log(4)
    }
    test()
    console.log(2)
    await cout_after10(8)
    await cout_after0(6)
    console.log(5)
})();

内容的提问来源于stack exchange,提问作者香辛料

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 15:07:51