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

通过示例理解Promise链式调用,解决登录逻辑实现难题

我懂你这种写得乱糟糟的痛苦!其实用async/await可以把这个登录逻辑梳理得非常清晰,完全贴合你的需求,而且代码可读性拉满。

先给你看优化后的完整代码:

@Post()
async login(
  @BodyParam('username', { required: true }) username: string,
  @BodyParam('password', { required: true }) plainPassword: string
): Promise<User | undefined> {
  // 第一步:根据用户名查找用户
  const user = await this.userService.findByUsername(username);
  
  // 用户不存在?直接返回undefined,对应HTTP 404
  if (!user) {
    return undefined;
  }

  // 第二步:调用密码验证的Promise(返回布尔值)
  const isPasswordMatch = await this.passwordService.verify(plainPassword, user.hashedPassword);
  
  // 密码不匹配?抛出ForbiddenError,对应HTTP 403
  if (!isPasswordMatch) {
    throw new ForbiddenError('Invalid credentials');
  }

  // 所有验证通过,返回用户信息,对应HTTP 200
  return user;
}

为什么这个写法更好?

  • 扁平化逻辑:用async/await把异步操作变成类似同步的写法,彻底告别嵌套回调或者复杂的then/catch链式调用,每一步的逻辑分支一目了然
  • 精准匹配需求:
    • 用户不存在时直接返回undefined,完美对应你的404要求
    • 密码错误时抛出ForbiddenError,框架会自动映射为403状态码
    • 验证通过返回用户对象,对应200成功响应
  • 可维护性高:每一段代码只做一件事,后续修改逻辑(比如加额外验证)也非常方便

如果你的项目暂时不能用async/await,也可以用Promise链式写法,但可读性会差一些,比如:

@Post()
login(
  @BodyParam('username', { required: true }) username: string,
  @BodyParam('password', { required: true }) plainPassword: string
): Promise<User | undefined> {
  return this.userService.findByUsername(username)
    .then(user => {
      if (!user) return undefined;
      
      return this.passwordService.verify(plainPassword, user.hashedPassword)
        .then(isMatch => {
          if (!isMatch) throw new ForbiddenError('Invalid credentials');
          return user;
        });
    });
}

但还是强烈推荐async/await版本,代码干净太多了!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:58:27