我正在使用node express mongoose / mongo等构建一个restful api。我正在尝试输出一个特定用户所遵循的用户数组。这是架构。
var UserSchema = new mongoose.Schema({
username: {type: String, lowercase: true, unique: true, required: [true, "can't be blank"], match: [/^[a-zA-Z0-9]+$/, 'is invalid'], index: true},
email: {type: String, lowercase: true, unique: true, required: [true, "can't be blank"], match: [/\S+@\S+\.\S+/, 'is invalid'], index: true},
bio: String,
image: String,
following: [{ type: mongoose.Schema.Types.ObjectId, ref: 'User' }]
}, {timestamps: true});
因此,每个用户都有一个数组中的用户数组在'follow'键中。我正在尝试输出该列表,首先通过它自己的id查找用户记录,然后通过此数组进行映射以查找当前用户的关注用户。
router.get('/users/friends', auth.required, function(req, res, next) {
var limit = 20;
var offset = 0;
if(typeof req.query.limit !== 'undefined'){
limit = req.query.limit;
}
if(typeof req.query.offset !== 'undefined'){
offset = req.query.offset;
}
User.findById(req.payload.id)
.then(function(user){
if (!user) { return res.sendStatus(401); }
return res.json({
users: user.following.map(function(username){
User.findById(username)
.then(function(userlist){
console.log('userlist:',userlist.username);
return userlist.username;
})
.catch(next)
})
})
})
.catch(next);
});
现在,此代码中的console.log在js控制台中输出正确的数据,但我似乎无法找到将其传递给客户端的方法。到目前为止,我的努力在客户端带来了“无效”价值。正确的记录数量,但只是空值。任何想法如何解决这个问题?
在下面的建议后修改我的代码。现在它设法将第一条记录发送到客户端,但随后出现错误
UnhandledPromiseRejectionWarning:未处理的承诺拒绝(拒绝ID:1):错误:发送后无法设置标头。 块引用
router.get('/users/friends', auth.required, function(req, res, next) {
var limit = 20;
var offset = 0;
if (typeof req.query.limit !== 'undefined') {
limit = req.query.limit;
}
if (typeof req.query.offset !== 'undefined') {
offset = req.query.offset;
}
User.findById(req.payload.id)
.then(function(user) {
if (!user) {
return res.sendStatus(401);
}
Promise.all(
user.following
).then(function(userarray) {
console.log(userarray);
userarray.forEach(function(userid) {
Promise.all([
User.find({
_id: {
$in: userid
}
})
.limit(Number(limit))
.skip(Number(offset))
.populate('author')
.exec()
]).then(function(results) {
userdetails = results[0];
var userdetailsCount = results[1];
return res.json({
userdetails: userdetails.map(function(userdetail){
return userdetail;
})
});
})
})
})
})
.catch(next);
});
答案 0 :(得分:1)
您的问题部分是:
return res.json({
users: user.following.map(function(username){
User.findById(username)
.then(function(userlist){
console.log('userlist:',userlist.username);
return userlist.username;
})
.catch(next)
})
})
位User.findById(username)
将返回一个承诺。但你不是在等待这个承诺。我猜你认为遵循该承诺的then
函数会将userlist.username
记录到控制台并返回它,这应该意味着你的map
函数返回userlist.username
列表1}}'第但这种情况并非如此。您的map
函数正在返回一系列承诺。
你真正想要的是像Bluebird的Promise.map
:http://bluebirdjs.com/docs/api/promise.map.html这样的功能(或者,寻找一个类似的功能,处理承诺数组,无论你发生在哪个承诺库中正在使用)。