Mongoose查询外部变量无法访问,需多查询后统一渲染EJS
问题
我尝试使用Mongoose查询所有用户,并将结果传入res.render()以在EJS文件中展示。
以下是我的代码:
const customersView = (req, res) => { const emailsArr = []; User.find({}, function(err, users) { users.forEach(function(user) { emailsArr.push(user.email); }); console.log('Inside: ' + emailsArr); // I can put res.render() here }); console.log('Outside: ' + emailsArr); // But I have to do some more queries here and then send them back all at once res.render('customers.ejs', {users: emailsArr}); }
但在User.find()外部,emailsArr为空。
控制台输出如下:
[nodemon] restarting due to changes... [nodemon] starting `node index.js` Server started Connected to MongoDB Outside: Inside: test@test,admin@admin
我可以在find()内部调用res.render(),但问题是我需要在该用户查询之后执行更多查询,再将所有结果一次性传递给EJS。请问该如何解决?
解决方案
这是因为Mongoose的查询是异步操作,代码会先执行User.find()外部的console.log和res.render,此时查询还没完成,所以emailsArr是空的。要解决多查询后统一渲染的问题,有几种常用方法:
方法1:Promise链式调用(适合少量后续查询)
Mongoose的查询方法默认返回Promise,可通过.then()链式处理多个查询:
const customersView = (req, res) => { // 第一个查询:只获取用户email字段,提升效率 User.find({}, 'email') .then(users => { const emailsArr = users.map(user => user.email); // 示例:执行第二个查询,比如获取订单数据 return Order.find({}).then(orders => ({ emailsArr, orders })); }) .then(({ emailsArr, orders }) => { // 所有查询完成后统一渲染 res.render('customers.ejs', { users: emailsArr, orders }); }) .catch(err => { console.error(err); res.status(500).send('服务器错误'); }); }
方法2:async/await(最清晰直观)
用async标记函数,await等待每个异步查询完成,逻辑和同步代码一致:
const customersView = async (req, res) => { try { // 等待用户查询完成 const users = await User.find({}, 'email'); const emailsArr = users.map(user => user.email); // 执行后续其他查询,比如获取客户统计数据 const customerStats = await Stats.findOne({ type: 'customer' }); // 可添加更多查询... // 所有数据就绪后渲染页面 res.render('customers.ejs', { users: emailsArr, customerStats }); } catch (err) { console.error(err); res.status(500).send('服务器错误'); } }
注意事项
- 避免嵌套过多回调(回调地狱),优先使用async/await或Promise链式写法
- 查询时指定需要返回的字段(如
User.find({}, 'email')),减少数据传输量 - 必须添加错误捕获逻辑,防止未处理的异常导致服务器崩溃
内容的提问来源于stack exchange,提问作者Phat Tran
相关产品推荐
相关产品推荐

