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

如何让JavaScript调用栈等待异步函数执行完成后再执行后续代码?

问题根源

两份代码的问题分为核心逻辑错误和语法错误两类:

  • 核心逻辑错误:first函数返回的Promise和内部的setTimeout完全没有绑定关系。调用setTimeout只是同步完成定时宏任务的注册动作,注册完成后代码会立刻向下执行,将返回的Promise置为已敲定状态,不会等待1秒/2秒后的打印逻辑执行。无论是.then链式调用还是await,都只会等待显式绑定的Promise状态变更,不会主动追踪函数内部游离的异步任务。
  • Promise写法的语法错误:.then(second())会在执行到then的瞬间同步调用second(),把执行结果(undefined)作为参数传入then,正确写法是传入函数引用.then(second),否则即使Promise时序正确,second也会提前执行。
  • async/await写法的逻辑错误:async函数执行到return true时就会立刻将返回的Promise标记为fulfilled状态,此时setTimeout的回调还在宏任务队列中等待计时结束,await拿到敲定状态后会立刻执行后续的second,导致顺序错乱。
修正方案

核心调整思路:让first返回的Promise,在setTimeout回调执行完成、打印出数字1之后再变更为已敲定状态,后续的second就会等待1打印完成后再执行。

修正后的Promise链式调用版本

function first(){
    // 自定义Promise,包裹setTimeout逻辑
    return new Promise((resolve) => {
        setTimeout(
            () => {
                console.log(1)
                // 打印1完成后再resolve,通知下游任务可以执行
                resolve(true)
            },
            1000
        )
    })
}

function second(){
    console.log(2)
}

function a(){
    first()
    // 传入函数引用,不要直接加括号调用second
    .then(second)
}

console.log("running...")
a()

修正后的async/await版本

// first直接返回Promise即可,不需要额外标记async
function first(){
    return new Promise((resolve) => {
        setTimeout( 
            () => {
                console.log(1)
                // 打印1完成后再resolve
                resolve(true)
            },
            2000
        )
    })            
}

function second(){
    console.log(2)
}

async function a(){
    await first()
    second()
}

console.log("running...")
a()

两份代码执行后都会先打印running...,等待对应定时时长后打印1,紧接着打印2,和预期输出一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 15:00:53