You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Express+Mongoose获取数据后无法存入列表的问题求助

问题:Express + Mongoose 无法将MongoDB数据存入列表传递给EJS模板

使用Express.js和Mongoose从MongoDB集合获取数据存入列表,再传递给EJS模板,但最终列表始终为空。以下是相关信息:

路由代码

app.get("/", (req, res) => {
  
    let item =  [];
    General.find(null, (err, data)=>{
            if(err){
              console.log(err); 
            } else {
                data.forEach(element => {
                    item.push(element.name);
                });
                console.log("pushed "+item);                 
            }
        });

    console.log("final  "+item);
    res.render("index", { title: "Welcome", list: item});
});

控制台输出

listening 3000
final
pushed item-1,item-2

数据库集合数据

[
  { _id: ObjectId("63d165717d847e937728e63b"), name: 'item-1', __v: 0 },
  { _id: ObjectId("63d165857d847e937728e63e"), name: 'item-2', __v: 0 }
]

项目配置信息

const express = require("express");
const bodyParser = require("body-parser");
const mongoose = require("mongoose");

mongoose.set("strictQuery", false);
mongoose.connect("mongodb://127.0.0.1:27017/todolistDB", { useNewUrlParser: true });
const genSchema = new mongoose.Schema({ name : String });
const General = mongoose.model("General", genSchema);

const app = express();
app.set('view engine', 'ejs');
app.use(bodyParser.urlencoded({ extended: "true" }));
app.use(express.static("public"));

问题原因与解决办法

问题核心

Mongoose的find方法是异步操作,不会阻塞后续代码执行。你的代码中,console.log("final " + item)和res.render在find的回调函数执行前就已经运行,此时item还未被填充数据,所以是空数组。控制台输出顺序(先打印final,再打印pushed)也验证了这一点——异步回调在主流程代码执行完后才触发。

解决方式1:将渲染逻辑移到回调内部

把res.render放在find的回调函数里,确保数据获取并处理完成后再渲染模板:

app.get("/", (req, res) => {
  
    let item =  [];
    General.find(null, (err, data)=>{
            if(err){
              console.log(err); 
              res.status(500).send("获取数据失败");
            } else {
                data.forEach(element => {
                    item.push(element.name);
                });
                console.log("pushed "+item);
                console.log("final  "+item);
                // 数据就绪后再渲染模板
                res.render("index", { title: "Welcome", list: item});
            }
        });
});

解决方式2:使用async/await(推荐)

利用async/await语法让异步代码更易读,逻辑更清晰:

app.get("/", async (req, res) => {
    try {
        let item = [];
        // 等待find操作完成,拿到数据
        const data = await General.find(null);
        data.forEach(element => {
            item.push(element.name);
        });
        console.log("pushed "+item);
        console.log("final  "+item);
        res.render("index", { title: "Welcome", list: item});
    } catch (err) {
        console.log(err);
        res.status(500).send("获取数据失败");
    }
});

两种方式都能保证在数据处理完成后,再将列表传递给EJS模板,模板就能拿到正确的非空数据了。

内容的提问来源于stack exchange,提问作者Shubham Verma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 12:10:54