Node.js中async/await结合for循环问题:未获取noOfContracts字段
问题解决:async/await循环中添加的noOfContracts字段未返回
核心原因
你通过Contact.find()获取的cons是Mongoose文档实例数组,而非普通JavaScript对象。Mongoose会严格按照定义的Schema字段进行序列化,直接给文档实例添加额外字段(如noOfContracts)不会被自动包含在返回的JSON结果中。
解决方案
方案1:查询时直接返回普通对象(推荐)
在Contact.find()中添加lean()选项,直接获取普通JS对象,后续添加字段无需额外转换:
// 原查询改为带lean(),直接返回普通对象 const cons = await Contact.find(where).lean(); const cons2 = await countContracts(cons); res.send(cons2); async function countContracts(cons) { for (let i = 0; i < cons.length; i++) { cons[i].noOfContracts = await Contract.countDocuments({ contactId: cons[i]._id, }); } return cons; }
方案2:将Mongoose文档转换为普通对象
如果无法修改查询语句,可先把文档实例转成普通对象再添加字段:
async function countContracts(cons) { // 转换为普通JS对象数组 const plainContacts = cons.map(doc => doc.toObject()); for (let i = 0; i < plainContacts.length; i++) { plainContacts[i].noOfContracts = await Contract.countDocuments({ contactId: plainContacts[i]._id, }); } return plainContacts; }
方案3:用Mongoose的set方法添加字段
若需保留Mongoose文档的其他功能,可通过set方法添加字段,最后转换为对象返回:
async function countContracts(cons) { for (let i = 0; i < cons.length; i++) { // 使用set方法给文档添加字段 cons[i].set('noOfContracts', await Contract.countDocuments({ contactId: cons[i]._id, })); } // 转换为普通对象数组后返回 return cons.map(doc => doc.toObject()); }
性能优化:并行处理请求
你的原代码是串行执行每个计数查询,效率较低。可改用Promise.all并行发起所有请求,大幅缩短处理时间:
async function countContracts(cons) { const plainContacts = cons.map(doc => doc.toObject()); // 并行处理所有计数请求 await Promise.all(plainContacts.map(async contact => { contact.noOfContracts = await Contract.countDocuments({ contactId: contact._id, }); })); return plainContacts; }
内容的提问来源于stack exchange,提问作者NEET JASSI
相关产品推荐
相关产品推荐

