[英]Function returning empty array, how to solve it? Javascript, mongoose
I have a javascript, mongoose function which should return an array.我有一个 javascript, mongoose 函数,它应该返回一个数组。 So basically what I have is a user schema, and a shopping list schema.
所以基本上我拥有的是一个用户模式和一个购物清单模式。 User schema has a parameter which is authorizedLists, an array of shopping lists ids.
用户架构有一个参数,即authorizedLists,一个购物清单ID 数组。 What I want is, that by passing the user id as a parameter, I can show those lists the user is authorized in. This function right now returns an empty array, and what I expected was an array with the shopping list objects.
我想要的是,通过将用户 ID 作为参数传递,我可以显示用户被授权进入的列表。这个函数现在返回一个空数组,我期望的是一个包含购物清单对象的数组。 I know it is not working due to Javascript asynchronous way of reading code, but I´m really stucked here.
我知道由于 Javascript 异步读取代码的方式,它不起作用,但我真的被困在这里。 Also I´m relatively new to nodejs and mongoose so I may have made other mistakes but haven´t realized yet.
另外,我对 nodejs 和 mongoose 比较陌生,所以我可能犯了其他错误,但还没有意识到。
Code:代码:
function getUserAuthLists(req,res){
const { userId } = req.params;
var list = [];
let i = 0;
User.findById( userId,async function(err, user){
if(err) return res.status(404).send(err);
console.log(user);
const array = user.authorizedLists;
console.log(array);
array.forEach( function(element){
console.log(element);
ShoppingList.findById(element , (error, result)=>{
if(error) {
console.log(error);
return res.status(404).send(error);
}
list.push(result);
console.log(list);
});
i++;
});
if(i === array.length) {
console.log(list);
return res.status(202).send(list);
}
});
}
Thanks in advance.提前致谢。
Refactor your function to use promises, collect all authorizedLists
and pass it in one-go using the $in
operator instead of repeatedly doing findById
重构您的函数以使用承诺,收集所有
authorizedLists
并使用$in
运算符一次性传递它,而不是重复执行findById
async function getUserAuthLists(req, res){
try {
const { userId } = req.params;
let i = 0;
const user = await User.findById(userId).exec();
const list = await ShoppingList.find({
_id: {
$in: user.authorizedLists
}
}).exec();
return res.status(202).send(list);
} catch (err) {
return res.status(404).send(err);
}
}
Since ShoppingList.findById is an i/o call, control does not wait by default to finish this call and directly jump to list.push(result);
由于ShoppingList.findById是一个i/o调用,控件默认不等待完成这个调用,直接跳转到
list.push(result);
with list empty values.带有列表空值。 You need to use promise to make it wait until it gets results from i/o call and then you should send back response.
您需要使用 promise 使其等待,直到它从 i/o 调用获得结果,然后您应该发回响应。 That way list will be updated for each array item call.
这样列表将针对每个数组项调用更新。
Something like this-像这样的东西——
async function getUserAuthLists(req, res) {
User.findById(userId, async function (err, user) {
if (err) return res.status(404).send(err);
console.log(user);
const array = user.authorizedLists;
console.log(array);
await ShoppingListFromDB(array)
.then((list) => {
console.log("list--", list);
return res.status(202).send(list);
})
.catch((error) => {
console.log(error);
return res.status(404).send(err);
})
});
}
function ShoppingListFromDB(array) {
return new Promise((resolve, reject) => {
let i = 0
var list = [];
for (const element of array) {
console.log("element ", element);
ShoppingList.findById(element, (error, result) => {
if (err) {
console.log(err)
return reject(error);
}
i++
list.push(result)
if (i == array.length) {
return resolve(list)
}
})
}
})
}
I have created a sample that simulated your requirement.我创建了一个模拟您的要求的示例。
https://github.com/ajaysikdar/test_server https://github.com/ajaysikdar/test_server
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.