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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 08:05:14