NodeJS callback after multiple async-functions in for-loop

后端 未结 2 510
谎友^
谎友^ 2021-01-24 10:47

I get a document from a mongodb which contains an array with comments for that document. In the comment is the _id of the user which wrote the comment.

I now need to ge

相关标签:
2条回答
  • 2021-01-24 11:28

    You can try like the following way

    const d = {
        "_id" : ObjectId("5c18c1cbc47e5e29d42e4b0e"),
        "completed" : false,
        "completedAt" : null,
        "comment" : [ 
            {
                "_id" : ObjectId("5c18c95e328c8319ac07d817"),
                "comment" : "This is a comment",
                "rating" : [ ],
                "user" : ObjectId("5c18b76e73236d2168eda2b4")
            }, 
            {
                "_id" : ObjectId("5c18fb578de5741f20a4e2bd"),
                "comment" : "Another comment",
                "rating" : [ ],
                "user" : ObjectId("5c18b76e73236d2168eda2b4")
            }
        ]
    }
    
    d.comment.forEach( async (obj, index) => {
        await new Promise((res) => {
                obj.counter = index;
                res();
        })
    });
    
    console.log(d);
    

    For reference please take a look on following link Asycn/Await using forEach

    0 讨论(0)
  • 2021-01-24 11:45

    There are serveral approaches you can use here based on your convenience

    Using async await

    let article = await Article.findOne({ _id: articleid }).lean().exec()
    
    await Promise.all(
      article.comment.map(async(obj) => {
        const user = await User.findOne({ _id: obj.user })
        obj.username = user.username
      })
    )
    
    console.log(article)
    

    Using $lookup aggregation 3.6

    Since mongodb has its own powerfull $lookup aggregation operator to join multiple collection and probably the better approach without any iteration

    Article.aggregate([
      { "$match": { "_id": mongoose.Types.ObjectId(articleid) }},
      { "$unwind": "$comment" },
      { "$lookup": {
        "from": "users",
        "let": { "userId": "$comment.user" },
        "pipeline": [
          { "$match": { "$expr": { "$eq": ["$$userId", "$_id"] }}}
        ],
        "as": "comment.user"
      }},
      { "$unwind": "$comment.user" },
      { "$group": {
        "_id": "$_id",
        "comment": { "$push": "$comment" },
        "completed": { "$first": "$completed" },
        "completedAt": { "$first": "$completedAt" }
      }}
    ])
    

    Using $lookup aggregation 3.4

    Article.aggregate([
      { "$match": { "_id": mongoose.Types.ObjectId(articleid) }},
      { "$unwind": "$comment" },
      { "$lookup": {
        "from": "users",
        "localField": "comment.user",
        "foreignField": "_id",
        "as": "comment.user"
      }}
      { "$unwind": "$comment.user" },
      { "$group": {
        "_id": "$_id",
        "comment": { "$push": "$comment" },
        "completed": { "$first": "$completed" },
        "completedAt": { "$first": "$completedAt" }
      }}
    ])
    
    0 讨论(0)
提交回复
热议问题