Node.js中跨文件函数无法返回数据问题求助
解决Node.js跨文件调用异步函数无法返回数据的问题
我帮你排查这个问题——你调用db.get后拿不到返回数据,90%的概率是异步操作没有正确处理。数据库查询这类IO操作几乎都是异步的,你直接用var ress = db.get(...)这种同步赋值的方式,肯定拿不到实际的查询结果,因为此时db.get还没执行完,ress要么是一个未resolved的Promise,要么就是undefined。
先分析你的代码问题
你的Login路由里直接赋值var ress = db.get(...),但db.get作为数据库查询方法,必然是异步执行的。我们需要根据它的异步实现方式(回调/Promise)来调整代码。
解决方案分两种情况:
情况1:db.get是基于回调的实现
如果你的Super类里的get方法是用回调函数返回结果(比如类似mysql模块的查询方式),那你需要把后续逻辑放到回调里执行:
router.post('/Login', function(req, res) { var username = req.headers['username']; var password = req.headers['password']; var md5pass = md5(password); // 把逻辑放到db.get的回调函数中 db.get('app_user', "username = '"+username+"' AND password = '"+md5pass+"'", function(err, data) { if (err) { // 处理数据库查询错误 return res.status(500).json({ success: false, message: '数据库查询失败' }); } // 这里才能拿到真实的查询结果data if (!data || data.length === 0) { return res.status(401).json({ success: false, message: '用户名或密码错误' }); } // 生成JWT返回给前端 const token = jwt.sign({ userId: data[0].id, username: data[0].username }, 'your-secret-key', { expiresIn: '1h' }); res.json({ success: true, token: token }); }); });
情况2:db.get是基于Promise的实现
如果你的Super类里的get方法返回Promise(比如用了async封装,或者用了bluebird这类库),那推荐用async/await来简化异步代码:
// 把路由处理函数标记为async router.post('/Login', async function(req, res) { try { var username = req.headers['username']; var password = req.headers['password']; var md5pass = md5(password); // 用await等待Promise完成,拿到真实结果 var ress = await db.get('app_user', "username = '"+username+"' AND password = '"+md5pass+"'"); if (!ress || ress.length === 0) { return res.status(401).json({ success: false, message: '用户名或密码错误' }); } // 生成JWT返回 const token = jwt.sign({ userId: ress[0].id, username: ress[0].username }, 'your-secret-key', { expiresIn: '1h' }); res.json({ success: true, token: token }); } catch (err) { // 捕获异步操作中的错误 res.status(500).json({ success: false, message: '数据库查询失败' }); } });
重要提醒:修复SQL注入风险
你现在直接把username和md5pass拼进SQL语句里,这是非常危险的SQL注入漏洞!一定要用参数化查询来避免这个问题。比如如果你的db.get支持参数占位符,可以改成这样:
// 用?作为占位符,把参数放到数组里传递 db.get('app_user', "username = ? AND password = ?", [username, md5pass], function(err, data) { // ... 后续逻辑 }); // 或者Promise版本 var ress = await db.get('app_user', "username = ? AND password = ?", [username, md5pass]);
这样既安全,又能避免字符串拼接带来的语法错误。
内容的提问来源于stack exchange,提问作者Irfan Alviansyah
相关产品推荐
相关产品推荐

