如何从Sqlite3的callback回调函数中获取返回的result值
核心原因
sqlite3的database.get是异步执行的API,你在回调函数里写的return只会把值返回给回调本身,外层的getUserByEmail函数会在数据库查询还没完成的时候就已经执行结束了,所以自然拿不到回调里的result值,不是变量只能在回调内部访问,是执行时序的问题。
解决方案:封装为Promise配合async/await使用
这是目前Node.js异步场景下最通用的实现方式,也适配Express的异步处理逻辑:
1. 重写getUserByEmail函数
const getUserByEmail = (targetEmail) => { return new Promise((resolve, reject) => { // 注意getUserByEmailQuery需要写为带占位符的预处理语句,比如: // const getUserByEmailQuery = `SELECT emailAddress FROM users WHERE emailAddress = ?` database.get(getUserByEmailQuery, [targetEmail], (err, result) => { if (err) { console.log(err.message); return reject(err); } // 符合需求:存在返回邮箱,不存在返回false resolve(result ? result.emailAddress : false); }); }); };
2. 调用方式
在需要调用该函数的位置,配合async/await使用即可拿到返回值,以Express路由为例:
// 路由处理函数需要加async关键字标记 app.post('/verify-email', async (req, res) => { try { const email = req.body.email; const checkResult = await getUserByEmail(email); if (checkResult) { // 邮箱存在的后续逻辑 res.json({ status: 'success', exist: true, email: checkResult }); } else { res.json({ status: 'success', exist: false }); } } catch (err) { res.status(500).json({ status: 'error', msg: '数据库查询异常' }); } });
补充说明
如果你不想用Promise,也可以给getUserByEmail增加回调参数来传递结果,但这种写法容易出现回调地狱,更推荐上述Promise的方案。另外注意一定要把邮箱作为参数传入预处理语句,不要直接拼接SQL,避免SQL注入风险。
内容的提问来源于stack exchange,提问作者Dantcho
相关产品推荐
相关产品推荐

