数据库查询异步执行导致变量未定义问题求助
解决异步查询导致变量未定义的问题
你遇到的核心问题是**await没有真正等待数据库查询完成**——因为你用的con.query是基于回调函数的异步API,而await只能等待Promise对象,所以代码会直接跳过查询逻辑,继续执行后面的console.log和业务代码,自然会出现number还没赋值就被打印的情况。
解决方案:将回调式查询转为Promise风格
我们需要把con.query封装成返回Promise的函数,这样就能用await正确等待异步操作完成。这里提供两种常用实现方式:
方式1:手动封装Promise
先写一个通用的Promise封装函数,适配所有查询场景:
// 封装con.query为Promise风格 function queryPromise(con, sql, params = []) { return new Promise((resolve, reject) => { con.query(sql, params, (err, rows) => { if (err) reject(err); else resolve(rows); }); }); }
然后修改你的业务代码,用await替代回调逻辑:
// 初始化变量,避免未定义问题 let turnback = false; // check if quote exists try { // 使用参数化查询避免SQL注入 const rows = await queryPromise(con, `SELECT * FROM quotes WHERE quote = ?`, [args.join(" ")]); if (rows[0]) { turnback = true; await client.say(channel, `That quote is already inside of the database!`); } } catch (err) { console.log(err); turnback = false; } // 如果quote已存在,直接终止流程 if (turnback) return; console.log("Quote Doesn't Exist"); // check amount of quotes in database let number; try { const rows = await queryPromise(con, `SELECT COUNT(*) AS cnt FROM quotes`); number = rows[0].cnt + 1; } catch (err) { console.log(err); number = 1; // 查询出错时默认设为1 } console.log("Checked Amount of quotes in database"); console.log(number); // insert quote into database let success; try { // 同样使用参数化查询 await queryPromise(con, `INSERT INTO quotes (quote, id) VALUES (?, ?)`, [args.join(" "), number]); success = true; } catch (err) { console.log(err); success = false; } // sending confirmation to user if (success) { await client.say(channel, `Successfully inserted quote #${number} into database`); } else { await client.say(channel, `Something went wrong, I failed to Insert The quote into the database!`); }
方式2:用Node.js内置的util.promisify
Node.js的util模块自带了把回调函数转为Promise的工具,写法更简洁:
const util = require('util'); // 把con.query转为Promise风格的函数,注意绑定上下文 const query = util.promisify(con.query).bind(con);
之后你可以直接用await query(sql, params)调用,业务逻辑和方式1完全一致,不需要自己写queryPromise函数。
重要提醒:防范SQL注入
你的原代码直接把用户输入的args.join(" ")拼接到SQL语句中,这会导致严重的SQL注入漏洞!上面的修正代码已经改用参数化查询(用?作为占位符,参数放在数组中传递),一定要坚持这种写法,绝对不要直接拼接用户输入到SQL里。
内容的提问来源于stack exchange,提问作者Supesu
相关产品推荐
相关产品推荐

