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

数据库查询异步执行导致变量未定义问题求助

解决异步查询导致变量未定义的问题

你遇到的核心问题是**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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 16:57:55