NodeJS应用如何在渲染HTML前执行两个MongoDB查询?
问题分析
你遇到的核心问题是异步操作的执行顺序:MongoDB的find().toArray()是异步方法,当你调用res.render的时候,这两个查询还没完成,所以res1和res2还是你初始化的undefined。另外还有个小问题:第一个查询完成后就调用了client.close(),这会导致第二个查询还没执行完就失去数据库连接,大概率会报错。
解决方案:用Async/Await处理异步操作
现在Node.js已经很好支持async/await,用它可以让异步代码看起来像同步代码,完美解决你的问题。下面是修正后的代码:
app.get('/technology/:technology', async function(req, res) { let client; try { // 1. 建立数据库连接 client = await MongoClient.connect('mongodb://xx.xxx'); const db = client.db('test'); // 2. 并行执行两个查询,等待所有结果返回 const [result1, result2] = await Promise.all([ db.collection('col1').find().toArray(), db.collection('col2').find().toArray() ]); // 3. 拿到结果后再渲染页面 res.render('technology', { tech1: result1, tech2: result2 }); } catch (err) { // 统一处理错误 console.error(err); res.status(500).send('服务器出错了'); } finally { // 不管成功失败,最后都关闭连接 if (client) { await client.close(); } } });
代码说明
- 把路由处理函数标记为
async,这样就能在里面用await关键字等待异步操作完成 - 用
try/catch/finally包裹代码:try块里处理连接、查询、渲染的正常逻辑catch块捕获所有可能的错误(连接失败、查询出错等),给用户返回友好的错误响应finally块确保不管成功还是失败,数据库连接都会被关闭,避免资源泄漏
Promise.all()用来并行执行两个查询,比逐个等待更高效,等两个查询都完成后再一起拿到结果- 不再用全局变量存结果,直接用
await拿到查询结果,彻底避免异步时序问题
这样修改后,你就能确保在渲染页面时已经拿到两个集合的查询结果,而且数据库连接也会正确关闭。
内容的提问来源于stack exchange,提问作者nicoschuck
相关产品推荐
相关产品推荐

