我对以下代码有疑问:
router.get('/friends', function(req, res) {
var friends=[];
var photos = [];
if (req.session && req.session.user) {
User.findOne({ email: req.session.user.email }, function (err, user) {
if (!user) {
req.session.reset();
res.render('login',{message:'Session is timed-out. Login to your account'});
}
else {
res.locals.user = user; // expose the user to the template
async.forEach (user.friends ,function (item,index, arr) {
friends.push(item);
var cursor = User.findOne({ email: item });
photos.push(cursor.coverPhotoUrl);
console.log(cursor);
});//
res.render('friends',{friends: friends, photos: photos});
}//else
});
} else {
res.render('login',{message:''});
}
});
我要做的是迭代用户的朋友(用户将他的朋友作为一系列字符串 - 他的朋友的电子邮件) 对于我检索的每个电子邮件地址,我正在尝试在数据库中查找特定用户,以获取他的“coverPhotoUrl”字段并将其插入到数组中。
完成所有这些之后,我想渲染一个页面并将它发送给我创建的两个数组,但是由于'findOne'查询中的回调函数在页面有后调用它会给我带来一些麻烦已经被渲染,所以我发送的数组是空的。
我该如何解决?
答案 0 :(得分:0)
async.forEach函数是异步的,因此它会立即返回,此时你的朋友和照片数组将是空的,因为它们还没有被填写。
forEach的第3个参数可以是回调,只有在完成所有迭代后才能完成。你应该把你的res.render放在那里。见https://github.com/caolan/async
答案 1 :(得分:0)
您可以尝试使用此代码。我已经尝试添加回调给findOne()调用朋友并添加到朋友。此外,您可以检查当前元素是否是最后一个元素,然后呈现页面
router.get('/friends', function(req, res) {
var friends = [];
var photos = [];
if (req.session && req.session.user) {
User.findOne({
email: req.session.user.email
}, function(err, user) {
if (!user) {
req.session.reset();
res.render('login', {
message: 'Session is timed-out. Login to your account'
});
} else {
res.locals.user = user; // expose the user to the template
async.forEach(user.friends, function(item, index, arr) {
friends.push(item);
// add callback to findOne Call
User.findOne({
email: item
}, function(err, cursor) {
if (cursor) {
photos.push(cursor.coverPhotoUrl);
console.log(cursor);
}
});
// ALSO CAN ADD LENGTH CHECK TO GET IF THE CURRENT ELEMENT IS LAST ELEMENT
if (user.friends.indexOf(item) == user.friends.length - 1) {
res.render('friends', {
friends: friends,
photos: photos
});
}
}); //
} //else
});
} else {
res.render('login', {
message: ''
});
}
});