通过示例理解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
相关产品推荐
相关产品推荐

