ModeMongoose 的 Async/Await with Mongoose Deep Populate Chain

ModeMongoose's Async/Await with Mongoose Deep Populate Chain

在使用 async/await 时,我在按顺序获取链式猫鼬命令 运行 时遇到了很多麻烦。一个简单的 await Model.find({}) 命令可以像人们预期的那样在异步函数中工作,但是当我为了深度填充的目的将 find 命令与 leanpopulateexec 链接时( http://mongoosejs.com/docs/populate.html#deep-populate) 我无法 运行 按我想要的顺序排列它们。

const messageSchema = new Schema({
  ...
})
const Message = mongoose.model("message", messageSchema)

const chatSchema = new Schema({
  conversations: [{
      messages: [{ type: Schema.Types.ObjectId, ref: "message" }]
  }]
})
const Chat = mongoose.model("chat", phoneSchema)

console.log("11111111111")

const chat = await Chat.findOne({ ... })
  .lean()
  .populate({ path: "conversations" })
  .exec(async (err, docs) => {
    const options = {
      path: "conversations.messages",
      model: "message",
    }

    const result = await Chat.populate(docs, options,
      (e, foundChat) => foundChat)

    console.log("22222222222")

    return result
  })

console.log("333333333333")

结果:

11111111
33333333
22222222

期望的结果:

111111111
222222222
333333333

不知道为什么,尝试了很多不同的东西,但这很有效。

const chat = await Chat.findOne({ ... })
  .populate({
    path: "conversations.messages",
    model: "message",
  })
  .exec((error, foundChat) => foundChat)

我觉得你的代码有 2 个问题:

  1. 使用 lean() 选项后不能调用 populate()。 Lean() 将 returned 对象变成常规 javascript 对象而不是 mongoose 文档。 Populate是mongoose内置的方法,所以只能在mongoose文档中使用。这与您的问题无关,但了解这一点很重要。

  2. 当您在查询上调用 exec() 并将回调作为参数传递时,它不会 return 承诺,因此 'await' 子句对其没有影响.这就是为什么您的函数不等待 Chat.findOne() 解析并直接进入最后一个 console.log 的原因。以下可能会起作用:

    const chat = await Chat.findOne({ ... })
     .populate({ path: "conversations" })
     .exec().then(async (docs) => {
       const options = {
         path: "conversations.messages",
         model: "message",
       }
    
       const result = await Chat.populate(docs, options)
    
       console.log("22222222222")
    
       return result
    })