简体   繁体   English

函数返回空数组,如何解决? Javascript,猫鼬

[英]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

server服务器在此处输入图片说明

client客户在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM