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

Node.js中Promise执行SQL语句顺序混乱,求正确顺序执行方案

Node.js Promise 实现SQL语句顺序执行问题

我正在学习Node.js与Promise,希望代码中的SQL语句能够顺序执行(一条执行完成后再执行下一条),但当前的Promise实现存在问题,终端输出显示SQL语句的执行顺序混乱(比如“done with three”先于“done with two”输出)。以下是我的代码和输出,求指导如何正确实现顺序执行:

其中一条SQL语句的Promise封装

var selectbotagentstoadd = new Promise((resolve, reject) => {
    var sql = 'SELECT tbltestbotagentstoadd.AgentID FROM tbltestbotagentstoadd WHERE tbltestbotagentstoadd.IDNumber=? AND tbltestbotagentstoadd.MSISDN=?;'
    DB.query(sql, [agentidpassnum, agentnumber], function(err, results) {
        if (err) {
            return reject(err);
        }; 
        return resolve(results);
    });
})

Promise调用语句

await insertbotagentstoadd.then(() => {
   console.log("done with one");
})
.then(() => { selectbotagentstoadd.then((results) =>
{
        AgenttoaddIDStore=[];
       results.forEach(agent => {
          AgenttoaddIDStore.push({
           AgentID:agent.AgentID
       });
        ctx.session.tempAgentID=agent.AgentID
       });
console.log("agent ID: "+ctx.session.tempAgentID);
console.log("done with two");
})})
.then((results) => {insertcctblricaagents
console.log("done with three");
})
.then((results) => {selectcctblricaagents.then((result) => {
    console.log(result);
            AgentnewIDStore=[];
            result.forEach(agent => {
                AgentnewIDStore.push({
                AgentID:agent.AgentID
            })
            ctx.session.AgentID=agent.AgentID
            })
            console.log("cctblricaagents agent ID: "+ ctx.session.AgentID);
            console.log("done with four");
})})
.then(insertcctblricaagentsnum.then((result) => {
console.log("done with five");
}))
.then(selectcctblricaagentsnum.then((result) => {
    console.log(result)
    AgentIDStore=[];
    result.forEach(agent => {
    AgentIDStore.push({
        AgentID:agent.AgentID,
        MainNumber:agent.MainNumber,
    })
    ctx.session.AgentID=agent.AgentID
    ctx.session.agentnumber=agent.MainNumber
    })
    console.log("cctblricaagentsnum agent ID: "+ ctx.session.AgentID);
    console.log("done with six");
}))
.then(insertcctblintblbotagents.then((result) => {
    console.log("done with seven");
}));

终端输出结果

Agent number: 27815567777
done with one
done with three
agent ID: 89
done with two
[]
cctblricaagents agent ID: null
done with four

问题根源

你的代码存在两个核心问题导致顺序混乱:

  1. .then()回调中调用内部Promise但未返回,导致当前回调结束后直接进入下一个.then(),不等待内部Promise完成。比如第二个.then()里执行selectbotagentstoadd.then()但没返回,第三个.then()直接执行,所以"done with three"先出现。
  2. 错误地将Promise的执行结果(而非回调函数)传给.then(),比如then(insertcctblricaagentsnum.then(...)),这种写法会让该Promise立即执行,不受链式流程控制。

正确实现方式

方式1:用async/await简化(推荐)

既然已经用到await,直接用顺序写法更直观,完全避免链式嵌套:

// 第一步:执行insertbotagentstoadd
await insertbotagentstoadd;
console.log("done with one");

// 第二步:执行select并处理结果
const selectResults = await selectbotagentstoadd;
AgenttoaddIDStore = [];
selectResults.forEach(agent => {
  AgenttoaddIDStore.push({ AgentID: agent.AgentID });
  ctx.session.tempAgentID = agent.AgentID;
});
console.log("agent ID: " + ctx.session.tempAgentID);
console.log("done with two");

// 第三步:执行insertcctblricaagents
await insertcctblricaagents;
console.log("done with three");

// 第四步:执行selectcctblricaagents并处理结果
const ricaAgentResults = await selectcctblricaagents;
console.log(ricaAgentResults);
AgentnewIDStore = [];
ricaAgentResults.forEach(agent => {
  AgentnewIDStore.push({ AgentID: agent.AgentID });
  ctx.session.AgentID = agent.AgentID;
});
console.log("cctblricaagents agent ID: " + ctx.session.AgentID);
console.log("done with four");

// 第五步:执行insertcctblricaagentsnum
await insertcctblricaagentsnum;
console.log("done with five");

// 第六步:执行selectcctblricaagentsnum并处理结果
const numResults = await selectcctblricaagentsnum;
console.log(numResults);
AgentIDStore = [];
numResults.forEach(agent => {
  AgentIDStore.push({
    AgentID: agent.AgentID,
    MainNumber: agent.MainNumber,
  });
  ctx.session.AgentID = agent.AgentID;
  ctx.session.agentnumber = agent.MainNumber;
});
console.log("cctblricaagentsnum agent ID: " + ctx.session.AgentID);
console.log("done with six");

// 第七步:执行insertcctblintblbotagents
await insertcctblintblbotagents;
console.log("done with seven");

方式2:修复原有的.then()链式调用

如果坚持用链式写法,必须确保每个.then()的回调返回要等待的Promise,让链式流程同步:

await insertbotagentstoadd
  .then(() => {
    console.log("done with one");
  })
  // 返回select的Promise,让链式等待它完成
  .then(() => {
    return selectbotagentstoadd.then((results) => {
      AgenttoaddIDStore = [];
      results.forEach(agent => {
        AgenttoaddIDStore.push({ AgentID: agent.AgentID });
        ctx.session.tempAgentID = agent.AgentID;
      });
      console.log("agent ID: " + ctx.session.tempAgentID);
      console.log("done with two");
    });
  })
  .then(() => {
    // 返回insert的Promise
    return insertcctblricaagents.then(() => {
      console.log("done with three");
    });
  })
  .then(() => {
    return selectcctblricaagents.then((result) => {
      console.log(result);
      AgentnewIDStore = [];
      result.forEach(agent => {
        AgentnewIDStore.push({ AgentID: agent.AgentID });
        ctx.session.AgentID = agent.AgentID;
      });
      console.log("cctblricaagents agent ID: " + ctx.session.AgentID);
      console.log("done with four");
    });
  })
  .then(() => {
    return insertcctblricaagentsnum.then(() => {
      console.log("done with five");
    });
  })
  .then(() => {
    return selectcctblricaagentsnum.then((result) => {
      console.log(result);
      AgentIDStore = [];
      result.forEach(agent => {
        AgentIDStore.push({
          AgentID: agent.AgentID,
          MainNumber: agent.MainNumber,
        });
        ctx.session.AgentID = agent.AgentID;
        ctx.session.agentnumber = agent.MainNumber;
      });
      console.log("cctblricaagentsnum agent ID: " + ctx.session.AgentID);
      console.log("done with six");
    });
  })
  .then(() => {
    return insertcctblintblbotagents.then(() => {
      console.log("done with seven");
    });
  });

关键注意事项

  • 所有需要等待的异步SQL操作,必须通过await或者在.then()中返回对应的Promise,才能纳入顺序执行的流程。
  • 禁止在.then()中嵌套Promise却不返回,这会导致内部异步操作脱离控制,打乱执行顺序。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 11:40:34