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

为什么Promise链式调用then后第2、3次数据获取仍异步运行

问题原因分析
  • 核心原因是:Promise链式调用的then方法,只有当前一个then的回调函数返回一个Pending状态的Promise实例时,后续的then才会等待该Promise状态变更后再触发。你写的代码中前两个then回调都没有返回自定义Promise,所以链式调用没有等待内部的setTimeout异步任务完成。
  • 具体执行逻辑拆解:
    1. 初始代码同步执行,依次打印Start Program、Start Getting Data 1,创建Promise实例后注册3秒的setTimeout,主线程继续执行打印End Program
    2. 3秒后第一个setTimeout触发,打印Got Data 1,Promise状态变为fulfilled,触发第一个then回调
    3. 第一个then同步执行打印Start Getting Data 2,然后注册第二个3秒的setTimeout,该回调没有返回任何值,默认返回状态为fulfilled的空Promise,所以第二个then会立刻触发,不需要等第二个setTimeout执行
    4. 第二个then同步执行打印Start Getting Data 3,注册第三个3秒的setTimeout,同样没有返回Promise,链式调用结束
    5. 再等3秒左右,第二个和第三个setTimeout几乎同时触发,先后打印Got Data 2、Got Data 3
正确实现串行异步的写法

如果要实现获取数据1完成后等3秒拿数据2,拿完数据2再等3秒拿数据3的串行效果,需要在每个then的回调里返回包裹了异步任务的新Promise:

console.log("Start Program")
console.log("Start Getting Data 1")

new Promise((succes) => {
    setTimeout(()=>{
        console.log("Got Data 1")
        succes()},3000)
    }
).then(()=>{
    // 返回新的Promise,下一个then会等待这个Promise resolve
    return new Promise((resolve) => {
        console.log("Start Getting Data 2")
        setTimeout(()=>{
            console.log("Got Data 2")
            resolve()
        },3000)
    })
}).then(()=>{
    return new Promise((resolve) => {
        console.log("Start Getting Data 3")
        setTimeout(()=>{
            console.log("Got Data 3")
            resolve()
        },3000)
    })
})

console.log("End Program")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 00:24:00