首页 > 解决方案 > 数据不会被推送到数组 nodeJS

问题描述

所以我基本上想做的是从现有的猫鼬文档中创建一个新的用户数组。我的数据库中有一个用户数组。每个用户都有一个属性 booksBorrowed,它也是一个数组,我需要将其替换为从图书模型中检索到的另一个对象。我知道我可以使用填充功能来做到这一点。但是在 booksBorrowed 数组中,我还有一些其他值,例如日期和布尔值。所以我不能使用那个功能。请帮帮我:)。提前致谢。

router.get("/users",isAdmin, function(req,res){
User.find({}, function(err, users){
    if (err){
        console.log(err);
    }
    else {
        var modifiedUsers = [];
        for (const user of users) {
            var booksBorrowed = [];
            function async pushBook(book) {
                await booksBorrowed.push(book)
            }
                if(user.booksBorrowed){
                    for (const book of user.booksBorrowed){
                        Book.findById(book[0], function(err, bookFound){
                            if(err){
                                console.log(err);
                            }
                            pushBook(bookFound);
                        });
                    };  
                } 
            console.log(booksBorrowed);
            user.booksBorrowed = booksBorrowed;
            modifiedUsers.push(user);
            };
        res.render("users", {users: modifiedUsers});
    }
});

当我 console.log(booksBorrowed) 我看到的只是一个空数组的列表。可能变量没有更新,或者推送过程没有完成,其余代码运行。

标签: javascriptexpressmongooseweb-applicationsasync-await

解决方案


您的代码存在许多问题。首先,它表明您不了解如何await工作,然后可能不了解它与 Promise 的关系。这里有几点:

  1. awaitawait仅当您的承诺与您尝试等待的异步操作相关联时才会做一些有用的事情。所以await booksBorrowed.push(book)没有任何用处。
  2. 你永远不想混合普通回调和承诺/等待,所以你应该切换到你的数据库调用的承诺版本,以摆脱代码中的普通回调,然后你可以使用它们返回的承诺await和控制流。
  3. 即使在错误情况下,您也必须始终发送 http 响应。因此,所有可能的错误代码路径仍必须发送 http 响应。
  4. 您的数组看起来可能存在问题,因为您的代码编写方式与您将每个用户添加到数组中的数组modifiedUsers完全相同。如果您的意思是只有借书的用户,那么您需要在您的问题中澄清这一点并调整逻辑以实际执行此操作。usersmodifiedUsers
  5. 您的逻辑还将数组截断user.booksBorrowed为仅是该数组中的第一项。因此,如果该数组中有不止一本书,它将永远不会被使用,并且您的代码将user.booksBorrowed仅替换为单个元素数组。这似乎不正确,但我不知道您希望这是什么逻辑。我不明白你为什么首先要更换user.booksBorrowed

这是解决前三个问题的重写版本:

router.get('/users', isAdmin, async function (req, res) {
    try {
        let users = await User.find({});
        let modifiedUsers = [];
        for (const user of users) {
            let booksBorrowed = [];
            if (user.booksBorrowed) {
                for (const book of user.booksBorrowed) {
                    let bookFound = await Book.findById(book[0]);
                    booksBorrowed.push(bookFound);
                }
            }
            user.booksBorrowed = booksBorrowed;
            modifiedUsers.push(user);
        }
        res.render('users', { users: modifiedUsers });
    } catch (e) {
        // log error and send error status
        console.log(e);
        res.sendStatus(500);
    }
});

请阅读并了解 Promise 是如何工作的,如何await使用 Promise 以及您的数据库如何使用 Promise。您需要知道这一点才能编写好的可靠代码。这是一个示例,但您需要自己学习这些概念。


推荐阅读