【问题标题】:Use async await inside mapping function在映射函数中使用 async await
【发布时间】:2020-02-09 11:12:19
【问题描述】:

在我的 Node Express 应用程序中,我想获取课程的所有 cmets,并通过在每个评论中添加 fullname 字段来修改每个评论。为了获取用户的全名,我在UserController.js 中定义了findFullNameByUserId 函数。我在CourseController.js 中使用findAllCommentsByLessonId(),如下所示。但是,当我使用它时,我总是得到一个空数组。如何在findAllCommentsByLessonId() 中使用findFullNameByUserId 以便将fullname 字段添加到每个评论对象?

CourseController.js

findAllCommentsByLessonId: async (courseId,lessonId,callback) => {
    Course.find({_id: courseId}, function(err, course) {
      if (err) {
        callback(err, null);
      } else {
        const lesson = course[0].lessons.filter(l => l._id !== lessonId)
        const comments = lesson[0].comments.map( async c => {
          try{
            const name = await UserController.findFullNameById(c.user)
            return (
              {
                userId: c.user,
                name: name,
                content: c.content
              }
            )
          }
          catch(err){
console.log(err)
          }
        })

// console.log(comments) --> This always prints [{}]
        callback(null, comments)   
    }
    });
  }

UserController.js

module.exports = {
    findFullNameById: async (userId) => {
        await User.find({_id: userId}, function(err, user) {
            if (err) {
                console.log(err)
            } else {
                return  user[0].name+" "+( user[0].lname ? user[0].lname : "") 

            }
          });
    }
}

【问题讨论】:

  • 数组方法.map()、.filter()、.find()、.reduce()、.forEach()等不理解promise,因此不会等待异步函数。将for 和while 与await 一起使用
  • 你循环访问db,如果有很多cmet会导致性能问题。当您从 db 检索 cmets 时,您需要获取 FullName。我猜你正在使用猫鼬,所以你可以使用填充。

标签: javascript node.js express async-await


【解决方案1】:

在CourseController.js 中,您可以使用async-await,也可以使用callback

async-await方式:

findAllCommentsByLessonId: async (courseId,lessonId) => {
    let course = await Course.findOne({_id: courseId});
    if (course){
        let lesson = course.lessons.find(l => l._id == lessonId);
        let comments = [];

        for(let comment of lesson.comments){
               let name = await UserController.findFullNameById(comment.user);
               comments.push({userId: comment.user,name: name,content: comment.content});
        }
      return comments;
    }else{
      return [];
      }
  }

回调方式:

findAllCommentsByLessonId: (courseId,lessonId,callback) => {
       Course.findOne({_id: courseId},function(err, course) {
          if (err) {
            callback(err, null);
          } else {
            let lesson = course.lessons.find(l => l._id == lessonId);
            let comments = lesson.comments;
                comments.map((comment)=>{

                  UserController.findFullNameById(comment.user).then(name=>{
                      return {userId: comment.user,name: name,content: comment.content};
                  });

               });
              callback(null, comments);
            }
        });
 }

【讨论】:

  • 您的第二个 sn-p 仍然会为 comments 生成一个 undefineds 数组。
  • 我通过使用async-await 方式让它工作,即第一个sn-p
【解决方案2】:

首先删除回调并实际使用await 的承诺。您尚未指定 find 是什么,但它很可能是一个支持 Promise 的现代库。所以写

async function findAllCommentsByLessonId(courseId, lessonId) {
  const [course] = Course.find({_id: courseId};
  const lesson = course.lessons.find(l => l._id !== lessonId);
  const comments = lesson.comments.map(async c => {
    const name = await UserController.findFullNameById(c.user)
    return {
      userId: c.user,
      name,
      content: c.content
    };
  });
}

module.exports.findFullNameById = async (userId) => {
  const [user] = await User.find({_id: userId});
  return user.name + " " + (user.lname ? user.lname : "");
};

然后您会注意到 comments 不是用户数组,而是用户承诺的数组,因此将其包装在 await Promise.all(…) 调用中。

【讨论】:

    【解决方案3】:

    正如@SuleymanSah 评论的那样,我尝试使用.populate 并且效果很好。对于他指出的确切原因,我认为这是正确的方法。以下是我的做法:

    Lesson.findOne({ _id: lessonId }).
    populate('comments.user').
    exec(function(err, lesson) {
      if (err) {
        console.log(err);
        return callback(err, null);
      }
      if (!lesson) {
        console.log("No record found");
        return callback(err, null);
      }
      return callback(null, lesson.comments);
    });
    

    【讨论】:

      猜你喜欢
      • 2020-11-07
      • 1970-01-01
      • 2019-04-06
      • 2020-08-01
      • 2021-08-06
      • 2022-01-27
      • 2019-10-04
      • 1970-01-01
      • 2021-08-15
      相关资源
      最近更新 更多