You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mongoose虚拟属性访问返回Promise {<pending>}而非实际值如何解决?

问题原因

你给虚拟属性的getter加了async关键字,所有async函数的返回值本质都是Promise对象,所以你直接访问sarah.postCount拿到的自然是Promise实例,而不是你想要的数值。getter内部的console.log能正确打印是因为await已经执行完异步查询后才输出的,但这个结果是包裹在Promise里返回的。

解决方案

这里提供两种常用适配方案,可按需选择:

方案1:访问虚拟属性时加await(快速适配)

因为这个虚拟属性返回的是Promise,你只需要在访问的时候加await就能拿到最终数值,仅修改测试代码即可:

it("calculates user's post count ", async () => {
  const sarah = await User.findOne({ username: "sarahsmith" })
  // 加await获取Promise的resolve结果
  const postCount = await sarah.postCount
  console.log(`SARAH POST COUNT`, postCount) // 输出 1
})

注意:这种方案每次访问postCount都会触发一次数据库查询,性能开销很高,只适合低频访问的场景。

方案2:改用虚拟populate + 计数(推荐,性能更优)

Mongoose内置了虚拟populate功能,搭配计数参数可以避免每次访问属性都手动查库,是更符合Mongoose设计规范的实现方式:
首先修改Schema定义,把原来的异步虚拟属性替换为虚拟populate配置:

userSchema.virtual("postCount", {
  ref: "Post", // 关联的模型名
  localField: "_id", // 本地关联字段
  foreignField: "userId", // 外键关联字段
  count: true // 只返回匹配的文档数量,不返回具体文档数组
})

然后查询用户的时候主动populate这个虚拟字段即可:

it("calculates user's post count ", async () => {
  // 查询时populate postCount字段
  const sarah = await User.findOne({ username: "sarahsmith" }).populate("postCount")
  console.log(`SARAH POST COUNT`, sarah.postCount) // 直接输出 1
})

该方案只会在查询用户的时候执行一次关联计数查询,不会每次访问属性都触发数据库请求,性能更优,也符合Mongoose的最佳实践。

内容的提问来源于stack exchange,提问作者Jake Smith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 07:21:04