JWT授权开发问题:代码在第二个then阶段异步执行异常及邮箱校验变量值不符
兄弟,你这个问题典型的异步操作没等完就往下跑了!我给你拆解一下问题出在哪,再给你改好代码。
首先看你第一个then里的逻辑:你调用了userModel.query,这是个回调风格的异步函数——也就是说,它不会立刻执行完,而是等数据库查询返回结果后才会调用你传的(er, res)回调。但你在这个回调外面直接return(confirmed)了,这时候查询还在跑呢,confirmed还是初始的0!等后面回调执行把confirmed改成1的时候,第二个then早就已经执行过了,所以第二个then里拿到的confirmed自然是0,哪怕控制台后来打印出1也没用,时机不对。
还有你这个代码里的Promise链写得有点乱,明明用了async函数,却没好好利用await来简化异步流程,反而搞了一堆嵌套,很容易出问题。另外还要提醒你:直接把email拼进SQL语句里会有SQL注入风险,一定要用参数化查询!
给你重构一下代码,用更清晰的async/await风格,同时把回调转成Promise:
第一步:封装Promise版的查询工具
先把回调风格的userModel.query转成Promise,这样就能用await来等待异步操作完成:
// 封装Promise版的查询函数,统一处理回调 const runQuery = (sql, params = []) => { return new Promise((resolve, reject) => { userModel.query(sql, params, (err, result) => { if (err) { reject(err); } else { resolve(result); } }); }); };
第二步:重构registration函数
利用async/await让异步逻辑像同步代码一样清晰,彻底解决顺序问题:
async registration(email, password) { // 1. 检查邮箱是否已存在(用参数化查询避免SQL注入) const checkUserSql = 'SELECT id, email FROM user WHERE email = ?'; const existingUsers = await runQuery(checkUserSql, [email]); // 判断用户是否存在,存在则直接返回false if (existingUsers.some(user => user.email === email)) { console.log('User exists'); return false; } // 2. 获取lastadded中的son值,计算下一个用户ID const getSonSql = 'SELECT son FROM lastadded WHERE id = 1'; const sonResult = await runQuery(getSonSql); const nextUserId = sonResult[0].son + 1; // 3. 插入新用户 const insertUserSql = 'INSERT INTO user (email, password) VALUES(?, ?)'; await runQuery(insertUserSql, [email, password]); console.log('Fresh tea leaf'); // 4. 发送激活邮件 await mailService.sendActivationMail(email, '13'); // 5. 生成用户DTO和token,保存token const dto = new UserDto({ id: nextUserId, email, password }); const tokens = tokenService.generateTokens({ ...dto }); await tokenService.saveToken(dto.id, 'dsfsd'); // 返回成功结果,比如生成的tokens return tokens; }
关键改进点说明
- 异步操作严格等待:所有数据库查询都用
await等待完成,确保每一步拿到结果后再执行下一步,彻底解决你之前的顺序错误。 - 安全的参数化查询:把
email作为参数传入查询,避免了SQL注入风险,这是后端开发的基础安全规范。 - 简化逻辑结构:用
async/await替代嵌套的Promise链,代码可读性大幅提升,也不容易出现异步顺序问题。 - 去掉冗余变量:原代码里的
candidate、son等临时变量都被简化,直接用查询结果即可,逻辑更清爽。
这样改完之后,你之前的问题就完全解决了——检查用户存在的逻辑会等数据库查询完成后再判断,后续流程拿到的都是正确的状态值。
内容的提问来源于stack exchange,提问作者OskanZ
相关产品推荐
相关产品推荐

