You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;
}

关键改进点说明

  1. 异步操作严格等待:所有数据库查询都用await等待完成,确保每一步拿到结果后再执行下一步,彻底解决你之前的顺序错误。
  2. 安全的参数化查询:把email作为参数传入查询,避免了SQL注入风险,这是后端开发的基础安全规范。
  3. 简化逻辑结构:用async/await替代嵌套的Promise链,代码可读性大幅提升,也不容易出现异步顺序问题。
  4. 去掉冗余变量:原代码里的candidate、son等临时变量都被简化,直接用查询结果即可,逻辑更清爽。

这样改完之后,你之前的问题就完全解决了——检查用户存在的逻辑会等数据库查询完成后再判断,后续流程拿到的都是正确的状态值。

内容的提问来源于stack exchange,提问作者OskanZ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 09:52:33