为何db.all回调内salt正常输出,外部console.log显示undefined?
问题原因与解决方案
核心原因
这是异步操作的执行顺序问题。db.all()是Node.js中典型的异步数据库查询方法:它发起数据库查询后会立即返回,不会阻塞后续代码执行;只有当数据库查询完成、拿到结果后,传入的回调函数才会被调用。
你的代码实际执行顺序是:
- 声明变量
salt,初始值为undefined - 调用
db.all()发起异步数据库查询,此时回调函数还未执行 - 直接执行第二个
console.log(' SALT: ' + salt + 'saltEND2'),这时候salt还没被赋值,所以输出undefined - 一段时间后数据库查询完成,回调函数触发,给
salt赋值并执行第一个console.log,此时能输出正确值
解决办法
你需要把依赖salt的代码放到异步操作完成后执行,以下是两种常用方式:
方式1:将后续逻辑移入回调函数内
直接把第二个console.log(或其他需要使用salt的代码)移到回调函数中:
let salt; db.all( `SELECT salt FROM users WHERE username = ?`, [username], (err, row) => { if (err) throw err; salt = row[0].salt; console.log(' SALT: ' + salt + 'saltEND'); // 所有依赖salt的逻辑都放在这里 console.log(' SALT: ' + salt + 'saltEND2'); } )
方式2:使用Promise + async/await(更推荐,代码可读性更高)
如果你的数据库库支持Promise(比如sqlite3可通过util.promisify转换,或直接使用better-sqlite3这类原生支持Promise的库),可以用async/await改写:
const util = require('util'); // 将db.all转换为返回Promise的异步函数 const dbAllAsync = util.promisify(db.all.bind(db)); async function getSalt(username) { try { const row = await dbAllAsync(`SELECT salt FROM users WHERE username = ?`, [username]); const salt = row[0].salt; console.log(' SALT: ' + salt + 'saltEND'); console.log(' SALT: ' + salt + 'saltEND2'); return salt; } catch (err) { throw err; } } // 调用函数 getSalt(username);
这种写法会让代码按顺序执行:等待数据库查询完成并拿到salt后,再执行后续的console.log,自然能获取正确值。
内容的提问来源于stack exchange,提问作者BHughes
相关产品推荐
相关产品推荐

