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

调用searchAccessToken函数返回undefined问题(添加回调仍无效)

问题分析与解决方案

你遇到的核心问题是JavaScript异步操作的执行顺序,你的searchAccessToken函数里包含了异步的数据库操作(db连接和conn.query查询),但你试图用同步的方式返回结果,这就导致函数执行完毕时,异步操作还没完成,所以返回值是undefined。

先拆解下问题根源:

  • db(...)和conn.query(...)都是异步函数,它们的回调会在主线程空闲时才执行
  • 你原代码里的return token是在异步回调内部执行的,并不是searchAccessToken函数本身的返回值,所以外部调用searchAccessToken(name)时,函数已经提前返回了默认的undefined

你尝试用回调修改的版本也存在问题:

  • db的回调函数签名是固定的(err, conn),你不能凭空添加callback参数,这个参数根本不会被传入
  • 你调用searchAccessToken时也没有传入回调函数,即使写法正确,也无法获取结果

正确的回调写法

我们需要让searchAccessToken主动接受一个回调参数,在异步操作完成后调用这个回调来传递结果:

function searchAccessToken(emailAddress, callback) {
  // 重点:用参数化查询防止SQL注入,绝对不能直接拼接参数!
  var sql = "SELECT accessToken FROM device WHERE email_address = ?";
  console.log(sql);

  db(function(err, conn) {
    if (err) {
      return callback(err); // 把错误传递给回调
    }
    conn.query(sql, [emailAddress], function(err, results) {
      conn.release(); // 无论成功失败,都要释放数据库连接
      if (err) {
        return callback(err);
      }
      var token = results.length ? results[0].accessToken : "";
      callback(null, token); // 遵循Node.js回调规范:第一个参数是错误,第二个是结果
    });
  });
}

调用方式要改成传入回调函数:

searchAccessToken(name, function(err, userAccessToken) {
  if (err) {
    console.error("查询token失败:", err);
    return;
  }
  // 在这里使用userAccessToken,它会是预期的string类型
  console.log("获取到的用户token:", userAccessToken);
});

更优雅的Promise写法(推荐)

如果你的项目支持ES6+,可以把函数封装成Promise,避免回调嵌套的问题:

function searchAccessToken(emailAddress) {
  return new Promise((resolve, reject) => {
    var sql = "SELECT accessToken FROM device WHERE email_address = ?";
    console.log(sql);

    db(function(err, conn) {
      if (err) {
        return reject(err);
      }
      conn.query(sql, [emailAddress], function(err, results) {
        conn.release();
        if (err) {
          return reject(err);
        }
        var token = results.length ? results[0].accessToken : "";
        resolve(token);
      });
    });
  });
}

调用时可以用async/await让代码更像同步逻辑:

async function getUserToken() {
  try {
    var userAccessToken = await searchAccessToken(name);
    console.log("获取到的用户token:", userAccessToken);
    // 在这里处理token
  } catch (err) {
    console.error("查询token失败:", err);
  }
}

getUserToken();

关键安全提醒

你原来的代码直接把emailAddress拼接到SQL语句中,这会导致严重的SQL注入漏洞!一定要用参数化查询(上面代码里的?占位符和[emailAddress]参数数组),让数据库驱动帮你处理参数转义,避免恶意攻击。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:09:07