如何使saveUser函数返回bcrypt回调内数据库插入的用户记录?
问题:如何让saveUser函数返回数据库插入的用户记录?
我编写了一个将用户保存到数据库的saveUser函数,代码如下:
exports.saveUser = ({ first_name, last_name, email, password }) => { const query = "insert into users (first_name, last_name, email, password_hash) values ($1, $2, $3, $4) RETURNING *"; bcrypt.hash(password, 10, async function (err, hash) { const res = await db.query(query, [first_name, last_name, email, hash]); return res.rows[0]; }); return res; };
该函数中,bcrypt.hash的回调是一个async函数,在其中执行数据库插入操作并返回插入的行记录。我想知道如何让外层的saveUser函数最终返回这个res.rows[0]记录?
解决方案
你的代码存在两个核心问题:
- 回调函数内的返回值无法传递到外层
saveUser函数,因为回调是异步执行的,外层函数会先于回调完成执行。 - 最后一行的
return res完全无效,res仅在回调函数的作用域内定义,外层无法访问该变量。
推荐方案:使用Promise+async/await(主流写法)
摒弃回调写法,改用bcrypt.hash的Promise版本,配合async/await让逻辑线性化,代码更简洁易读:
exports.saveUser = async ({ first_name, last_name, email, password }) => { const query = "insert into users (first_name, last_name, email, password_hash) values ($1, $2, $3, $4) RETURNING *"; // 直接await bcrypt.hash的Promise结果 const hash = await bcrypt.hash(password, 10); const res = await db.query(query, [first_name, last_name, email, hash]); return res.rows[0]; };
调用该函数时,需要使用await或.then()获取返回的用户记录。
备选方案:手动封装Promise(兼容回调场景)
如果必须保留回调写法,可以将整个函数包装成Promise,手动控制结果的返回:
exports.saveUser = ({ first_name, last_name, email, password }) => { const query = "insert into users (first_name, last_name, email, password_hash) values ($1, $2, $3, $4) RETURNING *"; return new Promise((resolve, reject) => { bcrypt.hash(password, 10, async (err, hash) => { if (err) { // 抛出加密错误 return reject(err); } try { const res = await db.query(query, [first_name, last_name, email, hash]); resolve(res.rows[0]); } catch (dbErr) { // 抛出数据库操作错误 reject(dbErr); } }); }); };
内容的提问来源于stack exchange,提问作者Gia Nebieridze
相关产品推荐
相关产品推荐

