为何我的Promise有时返回数据库行,有时却不返回?
问题根源分析与修复方案
你的Promise时而返回数据库行、时而不返回的核心原因有两个,咱们一步步拆解:
1. SQL插入语句的字段与值不匹配
看你的insert语句:
insert into users (phonenumber,status,exitStatus) values ('+phonenumber+') returning *
你明确指定了要插入phonenumber、status、exitStatus三个字段,但values里只提供了phonenumber的值。这时候会出现两种情况:
- 如果
status和exitStatus字段设置了默认值或者允许为空(null),数据库会自动填充默认值/空值,插入成功,Promise就会resolve并返回行数据; - 如果这两个字段既没有默认值也不允许为空,数据库会直接抛出插入错误,触发Promise的
reject分支,这时候如果你的调用代码没处理catch,就会看起来"没有返回"。
2. 字符串拼接SQL的潜在风险(顺带修复)
你用字符串拼接的方式生成SQL语句,不仅有严重的SQL注入风险,还可能因为手机号的格式问题(比如包含特殊字符)导致插入失败。node-postgres支持参数化查询,能完美解决这个问题。
修复后的代码
db模块的addUser函数修正
module.exports={ addUser: function(phonenumber){ return new Promise(function(resolve,reject){ // 方案1:只插入phonenumber,让数据库处理其他字段的默认值/空值 const queryStr = 'insert into users (phonenumber) values ($1) returning *'; // 方案2:明确指定所有字段的值(如果需要手动设置status和exitStatus的话) // const queryStr = 'insert into users (phonenumber, status, exitStatus) values ($1, $2, $3) returning *'; // 使用参数化查询,避免SQL注入和格式错误 pool.query(queryStr, [phonenumber], (err,res)=>{ if (err){ reject(err); } else{ resolve(res.rows[0]); // 直接返回插入的行数据,更直观 } }); }); } }
调用代码的完善(添加错误处理)
var number = '123456789'; // 注意手机号最好用字符串类型,避免大数精度问题 testAddUser(number); async function testAddUser(phonenumber){ try { const user = await db.addUser(phonenumber); console.log('插入成功:', user); } catch (err) { console.error('插入失败:', err); // 这里能捕获到数据库抛出的错误,方便排查 } }
额外建议
- 检查你的
users表结构,确认status和exitStatus字段的约束(是否允许为空、有没有默认值),这能帮你理解为什么有时成功有时失败; - 尽量用
async/await替代原始的Promise回调,代码可读性更高; - 始终处理Promise的
catch分支,否则错误会被静默吃掉,难以排查问题。
内容的提问来源于stack exchange,提问作者sigil
相关产品推荐
相关产品推荐

