Mongoose两种实例方法执行结果不一致,求原因解析
问题解析:Mongoose实例方法then/async-await版本的行为差异
核心原因是异步操作的执行时机问题,两种写法的异步流程控制逻辑本质不同:
1. 基于Promise then的版本问题所在
假设你的then版本代码大致如下:
userSchema.methods.setPassword = function(password) { bcrypt.hash(password, 10) .then(hash => { this.hashedPassword = hash; }); };
这个方法里,bcrypt.hash是异步操作,会在后台执行,但setPassword本身没有等待这个操作完成,也没有返回对应的Promise。当你调用user.setPassword(password)后立刻执行user.save(),此时bcrypt.hash的回调还没触发,this.hashedPassword还没被赋值,所以save操作不会包含这个字段。
2. async/await版本为什么能正常工作
async/await版本的代码:
userSchema.methods.setPassword = async function(password) { const hash = await bcrypt.hash(password, 10); this.hashedPassword = hash; };
- async方法默认返回一个Promise,
await会暂停方法执行,直到bcrypt.hash的Promise完成并返回哈希值,之后才会给this.hashedPassword赋值。 - 调用时只要等待
setPassword完成(比如用await user.setPassword(password)),再执行save,此时字段已经被正确赋值,自然能被保存到数据库。
修复then版本的方法
如果要保留then写法,需要让setPassword返回Promise,确保调用方可以等待异步操作完成:
userSchema.methods.setPassword = function(password) { return bcrypt.hash(password, 10) .then(hash => { this.hashedPassword = hash; }); };
调用时要等待Promise完成后再save:
// 方式1:用await await user.setPassword(password); await user.save(); // 方式2:用then链 user.setPassword(password).then(() => user.save());
内容的提问来源于stack exchange,提问作者Stab-the-cake
相关产品推荐
相关产品推荐

