如何用Node.js在单个GET请求中从MongoDB多表传数据至EJS页面
解决MongoDB多集合查询后一次性传递数据到EJS页面的问题
你的问题核心在于两次调用res.render()——因为res.render()会立即向客户端发送响应,第一个调用完成后,第二个调用就不会被执行了,所以页面只能拿到其中一组数据。我们需要等两个集合的查询都完成后,再一次性把两组数据传递给landing.ejs。
这里有几种优雅的解决方式:
方法1:使用async/await(推荐,代码更清晰)
利用MongoDB驱动支持Promise的特性,结合async/await让异步代码看起来像同步代码,等两个查询都完成后再渲染页面:
app.get("/", async function(req, res) { try { // 并行查询两个集合 const founda = await as.find({}).exec(); const foundb = await bs.find({}).exec(); // 一次性传递两组数据到页面 res.render("landing", { a: founda, b: foundb }); } catch (err) { // 统一处理错误 console.log(err); res.status(500).send("服务器出错啦"); } });
方法2:使用Promise.all并行查询
如果你的Node环境对async/await支持有限,可以用Promise.all来并行处理两个异步查询:
app.get("/", function(req, res) { // 将查询转为Promise const queryA = as.find({}).exec(); const queryB = bs.find({}).exec(); // 等待两个Promise都完成 Promise.all([queryA, queryB]) .then(results => { const founda = results[0]; const foundb = results[1]; res.render("landing", { a: founda, b: foundb }); }) .catch(err => { console.log(err); res.status(500).send("服务器出错啦"); }); });
为什么原来的代码不行?
原来的写法中,as.find()和bs.find()是异步执行的,它们的回调函数会在查询完成后分别触发。第一个回调里的res.render()已经把响应发送给客户端了,第二个回调里的res.render()就没有意义了——HTTP响应只能发送一次。
不管用哪种方法,核心都是等待所有异步查询完成后,只调用一次res.render(),把两组数据同时传递给EJS模板。
内容的提问来源于stack exchange,提问作者rohitkhurana26697
相关产品推荐
相关产品推荐

