首页 > 解决方案 > 在调用 res.render() 之后发生 Mongoose 查找?

问题描述

我正在尝试使用 mongoDB 在 nodejs 中编写“facebook 克隆”。我遇到的问题是每次用户访问用户的个人资料时,他都需要获取他的朋友数组。我这样做的方式是这样的:

router.get("/user/:id/profile", isLoggedIn, (req, res) => {
let friends = [];
User.findById(req.params.id, (err, user) => {
    if (err) {
        req.flash("error", "There has been an error going to this persons profile.");
        res.redirect("back");
    } else {
        if (user.friends.length > 0) {
            for(var i = 0; i < user.friends.length; i++) {
                User.findById(user.friends[i], (err, friend) => {
                    if (err) {
                        console.log(err);
                        req.flash("error", "Could not find the friends list")
                        res.redirect("back")
                    } else {
                        friends.unshift({
                            firstName: friend.firstName,
                            lastName: friend.lastName,
                            _id: friend._id
                        })
                        console.log(friends)
                    }
                });
            }
            console.log(friends, "158")
            res.render("user", { userData: user, friends: friends })
        } else {
            // render the page without the friends array.
            res.render("user", { userData: user }); // im calling it userData because i have a local template variable called user and i don't want to over-write it
        }
    }
});
});

发生的事情是我在 for 循环中执行 console.log(friends) 时,我得到了所有正确的朋友数组,但是当我在 res.render("user ") 数组为空。知道为什么吗?

标签: javascriptnode.jsexpressmongoose

解决方案


在为 node.js 编写代码时,您需要习惯异步函数,因为很多插件/类/代码都使用它。

编码不再是“线性的”,而是在之前的代码完成后立即调用函数。

在您的情况下,findById开始在 mongoDB 中查找文档的过程,一旦找到它们,它将调用(在您的情况下为匿名)带有参数的回调函数(err, friend)

您的调用res.render不在该回调范围内,将在findById开始后立即调用。也就是来早了。
您需要将您res.render的回调放入回调中以获取数据。

编辑:由于for循环,以下代码将无法正常运行。我们需要使用如 Prajvals 回答中所示的承诺。请使用他的第二个示例,因为该示例有效。

User.findById(user.friends[i], (err, friend) => {
    if (err) {
        console.log(err);
        req.flash("error", "Could not find the friends list")
        res.redirect("back")
    } else {
        friends.unshift({
            firstName: friend.firstName,
            lastName: friend.lastName,
            _id: friend._id
        })
        console.log(friends);
        res.render("user", { userData: user, friends: friends })
    }
});

推荐阅读