[英]Use async await inside mapping function
In my Node Express App, I want to get all comments for a lesson and modify each comment by adding a fullname
field to each comment.在我的 Node Express 应用程序中,我想获取课程的所有评论并通过向每个评论添加fullname
段来修改每个评论。 For getting full name of a user, I have defined findFullNameByUserId
function in UserController.js
.为了获取用户的全名,我在UserController.js
定义了findFullNameByUserId
函数。 I use findAllCommentsByLessonId()
in CourseController.js
as follows.我在CourseController.js
使用findAllCommentsByLessonId()
如下。 However, when I'm using it, I always get an empty array.但是,当我使用它时,我总是得到一个空数组。 How can I use findFullNameByUserId
in findAllCommentsByLessonId()
so that fullname
field can be added to each comment object?如何在findAllCommentsByLessonId()
使用findFullNameByUserId
以便可以将fullname
findAllCommentsByLessonId()
段添加到每个评论对象?
CourseController.js课程控制器.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用户控制器.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 : "")
}
});
}
}
in CourseController.js
either you can use async-await
or you can use callback
在CourseController.js
,您可以使用async-await
或您可以使用callback
async-await way :异步等待方式:
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 [];
}
}
callback way :回调方式:
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);
}
});
}
Start by dropping callbacks and actually using promises for await
.首先删除回调并实际使用await
承诺。 You haven't specified what find
is, but chances are it's a modern library supporting promises.您还没有指定find
是什么,但很可能它是一个支持 promise 的现代库。 So write所以写
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 : "");
};
Then you'll notice that comments
is not an array of users, but rather an array of promises for users, so wrap it in a await Promise.all(…)
call.然后你会注意到comments
不是一个用户数组,而是一个用户承诺的数组,所以将它包装在一个await Promise.all(…)
调用中。
As @SuleymanSah commented, I tried to use .populate
and it worked well.正如@SuleymanSah 评论的那样,我尝试使用.populate
并且效果很好。 I think this is the correct approach as for the exact reasons he's pointed out.对于他指出的确切原因,我认为这是正确的方法。 The following is how I did it:以下是我是如何做到的:
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);
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.