Node.js中Mongoose查询赋值后对象属性丢失问题咨询
问题分析与解答
问题场景
在Node.js中使用Mongoose操作查询数据数量并赋值给对象属性,代码如下:
... const ability_count = { api_count: 0, func_count: 0, event_count: 0 }; ... ability_count.api_count = await APIService.findByList({cid: comp_id}).length; ability_count.func_count = await FuncService.findByList({cid: comp_id}).length; ability_count.event_count = await EventService.findByList({cid: comp_id}).length; ... const result = {ability_count: ability_count}; rm.successMsg(); rm.setResult(result); res.send(rm)
前端收到的结果中ability_count为空对象:
result: { ability_count: {} }
预期应该是属性值为undefined的对象,但实际却丢失了所有属性。
核心原因
运算符优先级导致错误赋值
await的优先级低于成员访问(.),所以代码中await APIService.findByList(...).length的执行顺序是:先获取findByList返回对象的length属性,再对这个属性值执行await。- 不管
findByList返回的是Mongoose的Query对象还是Promise实例,它们本身都没有length属性,直接取.length会得到undefined,await undefined的结果依然是undefined。最终ability_count的三个属性都会被赋值为undefined。
- 不管
JSON序列化自动忽略undefined属性
当通过res.send(rm)发送响应时,Express会自动将对象序列化为JSON格式。而JSON.stringify()方法处理对象时,会自动忽略值为undefined的属性,所以原本带有三个undefined属性的ability_count,序列化后就变成了空对象,这就是前端收到空对象的直接原因。
正确写法
如果要获取符合条件的数据数量,有两种更合理的方式:
// 方式1:先await查询结果,再取数组长度 ability_count.api_count = (await APIService.findByList({cid: comp_id})).length; // 方式2:使用Mongoose的countDocuments直接统计数量(性能更优,推荐) ability_count.api_count = await APIService.countDocuments({cid: comp_id});
内容的提问来源于stack exchange,提问作者lilcandle
相关产品推荐
相关产品推荐

