EJS调用MySQL异步函数返回空值问题求助
EJS中调用返回Promise的函数获取不到数据的问题解决
问题根源
你的egallery.getContents(rows.tag)返回的是Promise对象,而非直接的数据库查询结果:
- EJS模板渲染是同步执行的,直接赋值时
contents拿到的是处于pending状态的Promise,不是实际的返回数据,所以JSON.stringify(contents)会输出Promise的内部结构(看起来像空对象或状态字段)。 - 控制台能打印数据是因为Promise内部的
conn.query执行成功,但外部没有等待Promise完成就直接取值了。
另外你的EJS代码里有个变量名冲突:rows.forEach(function (rows) { })里的参数rows覆盖了外层的数组变量,建议改成row避免混淆。
解决方案(推荐方案:后端提前组装数据)
模板层尽量不做异步操作,建议在路由/控制器里提前把所有需要的数据组装好,再传给EJS:
1. 修改后端路由代码
const egallery = require('./你的模块路径'); // 假设这是你的Express路由 app.get('/your-page', async (req, res) => { try { // 先获取所有标签 const tags = await egallery.getTags(); // 为每个标签获取对应的内容,组装成完整数据 const rowsWithContents = await Promise.all( tags.map(async tagItem => { const contents = await egallery.getContents(tagItem.tag); return { ...tagItem, contents }; }) ); // 把组装好的数据传给EJS res.render('你的模板文件名', { rows: rowsWithContents }); } catch (err) { console.error(err); res.status(500).send('服务器错误'); } });
2. 修改EJS模板代码
直接使用后端已经组装好的contents字段:
<% rows.forEach(function (row) { %> <tr> <td><%= row.tag %> <div> <%= JSON.stringify(row.contents) %> </div> </td> </tr> <% }) %>
备选方案(EJS异步渲染,不推荐)
如果必须在模板里做异步操作,可以开启EJS的异步渲染支持,但存在渲染时序问题,不建议使用:
1. 开启异步渲染
// 渲染模板时指定async选项 res.render('你的模板文件名', { rows }, (err, html) => { if (err) throw err; res.send(html); });
2. 修改EJS模板
使用async/await等待Promise完成:
<% rows.forEach(async function (row) { %> <tr> <td><%= row.tag %> <div> <% var contents = await egallery.getContents(row.tag) %> <%= JSON.stringify(contents) %> </div> </td> </tr> <% }) %>
⚠️ 注意:forEach中的async函数不会被等待,模板可能会先渲染完成,导致数据延迟显示或不显示,所以优先选择第一种方案。
内容的提问来源于stack exchange,提问作者hkguile
相关产品推荐
相关产品推荐

