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

Node.js中isValid函数始终返回undefined的解决求助

搞定你的isValid函数返回问题!

嘿,我来帮你捋清楚这个问题——你遇到的核心是异步操作的返回值陷阱,这在刚接触JavaScript异步编程的新手里特别常见,咱们一步步拆解:

为什么valid一直是undefined?

你写的con.query是个异步函数(数据库查询不会立刻完成,得等数据库返回结果),它的回调函数会在查询结束后才执行,但你的isValid函数在调用con.query之后就直接跑完了,根本没返回任何值!而回调里的return只是从回调函数本身返回,和外层的isValid半毛钱关系都没有——这就是为什么valid一直是undefined,而你加的console.log能正常执行(因为它在回调里,等查询完才跑)。

怎么解决?

有两种常用的方式,我都给你写清楚,你可以选适合自己的:

方法1:用回调函数(最基础的异步处理)

给isValid加个回调参数,等查询完成后把结果通过回调传出来:

// 调用的时候要传一个回调函数,拿到结果后再处理
isValid(houseNew, gameID, 1, function(err, result) {
    if (err) {
        console.error(err);
        return;
    }
    var valid = result;
    // 这里写拿到valid后要做的逻辑
});

function isValid(card, gameID, ph, callback) {
    var cardnumbers = 0;
    // 注意:改成参数化查询,避免SQL注入!
    con.query("SELECT * FROM games WHERE id = ?", [gameID], function (err, result) {
        if (err) {
            callback(err); // 把错误传给回调
            return;
        }
        var cards = [
            result[0].player1,
            result[0].player2,
            result[0].player3,
            result[0].player4,
            result[0].player5,
            result[0].house1,
            result[0].house2,
            result[0].house3,
            result[0].house4,
            result[0].house5
        ];
        for(var i = 0; i<10; i++) {
            if(cards[i] == card) {
                cardnumbers++;
            }
        }
        let returnValue;
        if(cardnumbers >= 4) {
            returnValue = 0;
        } else {
            if(ph == 0) {
                let lastCard, i=0;
                lastCard = cards[i];
                i++;
                while(i<=4 && lastCard != 0) {
                    lastCard = cards[i];
                    i++;
                }
                returnValue = lastCard == 0 ? i : 10;
            } else if (ph == 1) {
                let lastCard, i=0;
                lastCard = cards[i + 5];
                i++;
                while(i<=4 && lastCard != 0) {
                    lastCard = cards[i + 5];
                    i++;
                }
                returnValue = lastCard == 0 ? i : 10;
            }
        }
        callback(null, returnValue); // 把结果传给回调
    });
}

方法2:用async/await(更现代的写法,像同步代码一样)

把数据库查询包装成Promise,然后用async/await来处理异步,代码看起来更清爽:

// 先把con.query包装成Promise函数
function query(sql, params) {
    return new Promise((resolve, reject) => {
        con.query(sql, params, (err, result) => {
            if (err) reject(err);
            else resolve(result);
        });
    });
}

// 把isValid改成async函数
async function isValid(card, gameID, ph) {
    var cardnumbers = 0;
    try {
        // 用await等待查询结果,就像同步代码一样
        const result = await query("SELECT * FROM games WHERE id = ?", [gameID]);
        var cards = [
            result[0].player1,
            result[0].player2,
            result[0].player3,
            result[0].player4,
            result[0].player5,
            result[0].house1,
            result[0].house2,
            result[0].house3,
            result[0].house4,
            result[0].house5
        ];
        for(var i = 0; i<10; i++) {
            if(cards[i] == card) {
                cardnumbers++;
            }
        }
        if(cardnumbers >= 4) {
            return 0;
        } else {
            if(ph == 0) {
                let lastCard, i=0;
                lastCard = cards[i];
                i++;
                while(i<=4 && lastCard != 0) {
                    lastCard = cards[i];
                    i++;
                }
                return lastCard == 0 ? i : 10;
            } else if (ph == 1) {
                let lastCard, i=0;
                lastCard = cards[i + 5];
                i++;
                while(i<=4 && lastCard != 0) {
                    lastCard = cards[i + 5];
                    i++;
                }
                return lastCard == 0 ? i : 10;
            }
        }
    } catch (err) {
        throw err; // 抛出错误,让调用方处理
    }
}

// 调用的时候要注意:await只能在async函数里用,所以可以这样写
(async function() {
    try {
        var valid = await isValid(houseNew, gameID, 1);
        // 这里使用valid
    } catch (err) {
        console.error(err);
    }
})();

// 或者用.then的方式(适合不能用await的场景)
isValid(houseNew, gameID, 1)
    .then(valid => {
        // 这里使用valid
    })
    .catch(err => {
        console.error(err);
    });

重要提醒:别踩SQL注入的坑!

你原来的SQL语句是直接把gameID拼进去的,这非常危险,容易被SQL注入攻击。我上面的代码都改成了参数化查询(用?占位,然后把参数放在数组里),这是后端开发的基本安全规范,一定要记住哦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:08:15