下面的代码片段使用sails waterline ORM来进行数据库查询和发送响应。但是,执行流程很奇怪,map函数外部的代码在map函数执行完之前就已经运行了。 '我在地图之外'在我之前在地图中打印在控制台中'。我认为可以使用Promise或async / await来解决这个问题。我已尝试使用下面的Promise.all(),但它不起作用,响应总是一个空数组。如果你能举一个如何解决这类问题的例子,我将不胜感激。
allMembers: (req, res) => {
const projectId = req.params.id;
ProjectMembers.find({projectId: projectId}).exec( (err, members) => {
if(err) res.serverError("bad request!");
if(members.length === 0) res.notFound({message: "No members are found for this project!"});
let membersInfo = [];
let promise = Promise.all(members.map(m => {
User.findOne({id: m.userId}).exec( (err, user) => {
if(err) membersInfo.push({name: null, userId: null, email:null,rate:null, error: 'Internal error!'})
else if(!user) membersInfo.push({name: null, userId: null, email:null,rate:null, error: 'No user found'})
else membersInfo.push({name: user.name, userId: user.id, rate: m.rate, error: null})
console.log("i am inside of map");
})
}));
console.log("I am outsie of map")
promise.then( (resolve) => {return res.ok({members: membersInfo})});
}
答案 0 :(得分:2)
我打算告诉你“不要在.map
中使用查询”,但在查看时,我认为你的代码非常接近于工作。 Promise.all
的论证必须是一系列的承诺。每个User.findOne
确实是一个承诺 - 绊脚石是,一旦你使用.exec
它就不再返回一个承诺。
我认为答案是在.then
内而不是在.map
内进行处理:
ProjectMembers.find({projectId: projectId}).exec( (err, members) => {
if(err) return res.serverError("bad request!");
if(members.length === 0) return res.notFound({message: "No members are found for this project!"});
let promise = Promise.all(members.map(m => User.findOne({id: m.userId})));
promise.then( (values) => {
// values is the array of user objects returned from the array of queries
let membersInfo = values.map((user) => {
if (!user) {
return {name: null, userId: null, email:null,rate:null, error: 'No user found'};
} else {
return {name: user.name, userId: user.id, rate: m.rate, error: null};
}
});
return res.ok({members: membersInfo});
}, (err) => {
return res.serverError("Error finding users");
});
承诺只有一个失败回调,因此您无法单独捕获并处理查询错误(尽管您仍然可以单独处理未找到的结果)。