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

为何checkUserNameIsUsed函数未返回布尔值却返回undefined?

问题排查:checkUserNameIsUsed函数返回undefined的原因

问题场景

Admin类中的checkUserNameIsUsed函数用于检查数据库中是否存在指定用户名,预期逻辑是:用户名已存在返回false,不存在返回true,但实际调用时该函数返回undefined,导致判断逻辑失效。

原函数代码:

class Admin {
  // This function checks if the username is already used. Error in return of function
  checkUserNameIsUsed(userName, tableName, proprtieName) {
    try {
      let sqlQuery = `select * from ${tableName} where ${proprtieName} = '${userName}'`;
      connectToMysql();
      connection.connect((err) => {
        if (!err) {
          connection.query(sqlQuery, (err, result) => {
            if (!err) {
              if (result.length > 0) {
                console.log("this user name is used :", userName);
                return false;
              } else {
                return true;
              }
            }
            connection.end();
          })
        } else {
          console.log(err);
          connection.end();
          return false;
        }
      })
    } catch (error) {
      console.log(error);
    }
  }
}

调用代码:

// Check if the user name is used
if (admin.checkUserNameIsUsed(adminUserName,adminTable,adminUserNameInDB)===false){
  res.status(400).send("The user name is used. Please choose another username");
  return false;
}

核心原因

1. 异步回调的返回值无法传递到外层函数

connection.connect()和connection.query()都是异步操作,它们的回调函数里的return语句,只能返回给回调函数自身,无法传递到外层的checkUserNameIsUsed函数。外层函数会在异步操作执行完毕前就已经执行结束,没有任何返回值,所以默认返回undefined。

2. 外层函数没有返回逻辑

整个checkUserNameIsUsed函数没有在任何同步代码块中返回值,也没有通过异步机制(比如Promise)把结果传递出去,导致函数执行完没有输出。

3. 错误处理不完整

  • connection.query()的错误分支没有返回逻辑,即使查询出错,也不会传递任何结果;
  • 外层的try/catch只能捕获同步代码的错误,异步操作的错误无法被捕获到,进一步导致结果丢失。

修复方案

改用Promise封装异步逻辑,让函数能够正确返回异步操作的结果,同时优化SQL语句防止注入风险:

修复后的函数代码

class Admin {
  checkUserNameIsUsed(userName, tableName, proprtieName) {
    // 返回Promise对象,用于传递异步结果
    return new Promise((resolve, reject) => {
      try {
        // 改用参数化查询避免SQL注入
        const sqlQuery = `SELECT * FROM ${tableName} WHERE ${proprtieName} = ?`;
        connectToMysql();
        
        connection.connect((err) => {
          if (err) {
            console.log("数据库连接失败:", err);
            connection.end();
            resolve(false); // 连接失败时返回false
            return;
          }

          // 执行参数化查询
          connection.query(sqlQuery, [userName], (err, result) => {
            connection.end(); // 无论成功失败都关闭连接
            if (err) {
              console.log("查询出错:", err);
              resolve(false);
              return;
            }

            // 根据查询结果返回对应值
            if (result.length > 0) {
              console.log("用户名已被占用:", userName);
              resolve(false);
            } else {
              resolve(true);
            }
          });
        });
      } catch (error) {
        console.log("同步代码出错:", error);
        resolve(false);
      }
    });
  }
}

修复后的调用代码

由于函数返回Promise,调用时需要用async/await或者.then()处理异步结果:

// 用async/await调用(需要在异步函数中执行)
async function handleUsernameCheck() {
  const isUserNameAvailable = await admin.checkUserNameIsUsed(adminUserName, adminTable, adminUserNameInDB);
  if (!isUserNameAvailable) {
    res.status(400).send("用户名已被占用,请更换其他用户名");
    return false;
  }
  // 后续业务逻辑
}

// 或者用.then()链式调用
admin.checkUserNameIsUsed(adminUserName, adminTable, adminUserNameInDB)
  .then(isAvailable => {
    if (!isAvailable) {
      res.status(400).send("用户名已被占用,请更换其他用户名");
      return false;
    }
    // 后续业务逻辑
  });

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 06:27:18