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

Node.js中使用Promise操作MySQL后变量lesEquipes为何为空?

为什么第三个then里的lesEquipes变量为空?

这个问题我之前也碰到过,核心原因是异步操作的执行顺序没处理对,咱们一步步拆解:

问题根源

你在第一个then的循环里,对每个团队发起了查询成员的database.query请求,但这个请求是异步的——JavaScript不会等着它执行完再走下一次循环,而是会直接把所有异步请求“扔出去”,然后立刻执行循环后面的console.log,接着直接进入第三个then。这时候所有查询成员的请求还在后台跑,lesEquipes自然还没被填充,所以打印出来是空的。

解决方案:用Promise.all等待所有异步请求完成

我们需要把每个团队的成员查询操作包装成Promise,收集到一个数组里,然后用Promise.all等待所有Promise都执行完成后,再继续后续逻辑。同时还要修复一个严重的问题:你的SQL语句用了字符串拼接,存在SQL注入风险,必须改成参数化查询。

修改后的代码核心部分如下:

app.post('/visu',function(req,res){
    if((req.body.email == "john@gmail.com") && (req.body.mdp == "password")){
        var leUser = "administrateur";
        let lesEquipes = [];
        let test = 'Toto';

        database.query("select * from equipe order by id")
        .then( result => {
            // 收集所有团队成员查询的Promise
            const memberQueries = result.map(equipe => {
                const idEquipe = equipe.id;
                // 使用参数化查询避免SQL注入
                return database.query("select * from participant where equipe = ?", [idEquipe])
                .then(result2 => {
                    // 把团队和成员组合起来,存入lesEquipes
                    lesEquipes[idEquipe] = [equipe, result2];
                    console.log("Membres de l'équipe : " + equipe.nomEquipe);
                    console.log("COURANTE 2 "+ JSON.stringify([equipe, result2]));
                });
            });

            // 等待所有成员查询完成后,再进入下一个then
            return Promise.all(memberQueries);
        })
        .then(() =>{
            console.log("Contenu "+ JSON.stringify(test));
            console.log("Contenu "+ JSON.stringify(lesEquipes));
            res.render('visuEquipes.ejs', { user:leUser, equipes : lesEquipes});
        })
        .catch((err) => {
            console.log(err);
            database.close();
        });
    }
});

关键修改点说明

  1. 用Array.map替代for循环:把每个团队的处理逻辑转换成Promise,存入memberQueries数组。
  2. 参数化查询:把"select * from participant where equipe = " + result[i].id改成"select * from participant where equipe = ?", [idEquipe],既安全又符合MySQL驱动的最佳实践。
  3. Promise.all等待所有异步操作:只有当所有成员查询都完成后,才会进入下一个then,这时候lesEquipes已经被完全填充了。

另外还有个小细节:你原来代码里在内部then里重新声明了let test = 'AUTRE CHOSE';,这会覆盖外部的test变量,但因为是异步执行,外部的console.log还是会先打印原来的Toto,这个如果不是你想要的逻辑,也可以调整一下。

内容的提问来源于stack exchange,提问作者Eric D.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:17:50