为何Mongoose中populate与exec无法配合async/await使用?
Mongoose关联与populate/exec调用问题解析
模型定义
Task模型(关联所属用户)
const taskSchema = new Schema({ description: { type: String, trim: true, required: true }, completed: { type: Boolean, default: false, }, owner: { type: Schema.Types.ObjectId, ref: 'User', required: true } });
User模型(虚拟属性关联任务)
userSchema.virtual("tasks", { ref: "Task", localField: "_id", foreignField: "owner", });
遇到的问题
- async/await函数中调用
task.populate('owner').exec()报错exec is not a function
const main = async () => { const task = await Task.findById("6420aeeebda4e48924667034"); task.populate('owner').exec() .then((task) => { console.log(task.owner) }); }
- 非async链式调用可正常运行
const main = () => { Task.findById("6420aeeebda4e48924667034").populate('owner').exec() .then((task) => { console.log(task.owner) }); }
- Mongoose最新版文档示例无法运行,IDE提示exec返回Promise
Person. findOne({ name: 'Ian Fleming' }). populate('stories'). // only works if we pushed refs to children exec(function(err, person) { if (err) return handleError(err); console.log(person); });
问题原因解析
1. async/await中exec报错的核心原因
await Task.findById(...)已经把Query查询对象执行完毕,返回的是真实的Task文档实例。文档实例上的populate()方法返回的是文档本身(或Promise),不是Query对象——而只有Query对象才有exec()方法,自然会报错。
正确写法应该直接用await处理populate:
const main = async () => { const task = await Task.findById("6420aeeebda4e48924667034"); await task.populate('owner'); console.log(task.owner); }
2. 非async链式调用正常的原因
Task.findById(...)返回的是Query查询对象,Query的设计就是支持链式调用:populate()会继续返回Query对象,所以可以接着调用exec()来执行查询、返回Promise,整个流程符合Mongoose的查询链式API设计。
3. 最新版文档示例失效的原因
Mongoose 6.x及以后的版本,exec()方法不再支持传入回调函数,只会返回Promise。旧文档里的回调写法已经被废弃,所以IDE会提示exec()返回Promise,传入回调会直接报错。
现在的正确写法有两种:
// 方式1:async/await const main = async () => { try { const person = await Person.findOne({ name: 'Ian Fleming' }).populate('stories'); console.log(person); } catch (err) { handleError(err); } } // 方式2:Promise then/catch Person.findOne({ name: 'Ian Fleming' }) .populate('stories') .then(person => console.log(person)) .catch(err => handleError(err));
内容的提问来源于stack exchange,提问作者Starnec
相关产品推荐
相关产品推荐

