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

Node.js中通过render向EJS传递两个查询结果遇阻求助

解决EJS模板同时接收两个查询结果的问题

我来帮你搞定这个问题!看你的代码,现在的问题主要有两个:一是当前的接口都是直接返回JSON数据,没有把结果传给EJS模板;二是两个异步查询没有同步处理,没法同时把两个列表数据一起渲染到页面上。另外还有个小问题,connection.end()放在了异步回调外面,会在数据库查询完成前就关闭连接,大概率会导致查询失败。

下面一步步给你修正:

第一步:把DAO的查询方法改成返回Promise(更易处理异步)

如果你的DAO目前是用回调的方式,建议改成Promise,这样后续用async/await处理多个异步查询会更清晰:

// 修改UfesDAO的lista方法
class UfesDAO {
  constructor(connection) {
    this.connection = connection;
  }

  lista() {
    return new Promise((resolve, reject) => {
      this.connection.query('SELECT * FROM ufes', (err, results) => {
        if (err) return reject(err);
        resolve(results);
      });
    });
  }
}

// 同理修改CidadesDAO的lista方法
class CidadesDAO {
  constructor(connection) {
    this.connection = connection;
  }

  lista() {
    return new Promise((resolve, reject) => {
      this.connection.query('SELECT * FROM cidades', (err, results) => {
        if (err) return reject(err);
        resolve(results);
      });
    });
  }
}

第二步:创建统一的路由处理函数,同时获取两个列表并渲染EJS

写一个专门的路由函数,用Promise.all并行获取UF和城市列表,拿到结果后一起传给EJS模板:

// 处理表单渲染的路由函数
const renderFormPage = async (req, res) => {
  try {
    // 获取数据库连接
    const connection = app.infra.connectionFactory();
    const ufesDAO = new app.infra.UfesDAO(connection);
    const cidadesDAO = new app.infra.CidadesDAO(connection);

    // 并行执行两个查询,等待所有结果返回
    const [ufList, cityList] = await Promise.all([
      ufesDAO.lista(),
      cidadesDAO.lista()
    ]);

    // 查询完成后再关闭连接
    connection.end();

    // 把两个列表数据传给EJS模板(假设你的模板文件叫form.ejs)
    res.render('form', {
      ufOptions: ufList,
      cityOptions: cityList
    });
  } catch (error) {
    console.error('加载数据出错:', error);
    res.status(500).send('服务器加载数据失败,请稍后重试');
  }
};

// 绑定路由,比如访问/form时渲染页面
app.get('/form', renderFormPage);

第三步:在EJS模板里渲染下拉框

现在在你的EJS模板里,就可以用传过来的ufOptions和cityOptions生成下拉选项了:

<!-- form.ejs中的下拉框部分 -->
<div class="form-group">
  <label for="uf-select">选择UF:</label>
  <select id="uf-select" name="uf" class="form-control">
    <% ufOptions.forEach(uf => { %>
      <option value="<%= uf.id %>"><%= uf.nome %></option>
    <% }) %>
  </select>
</div>

<div class="form-group">
  <label for="city-select">选择城市:</label>
  <select id="city-select" name="cidade" class="form-control">
    <% cityOptions.forEach(city => { %>
      <option value="<%= city.id %>"><%= city.nome %></option>
    <% }) %>
  </select>
</div>

关键要点说明

  • 异步处理:用Promise.all可以让两个数据库查询并行执行,比嵌套回调更高效也更易读;async/await让异步代码看起来像同步代码,降低出错概率。
  • 连接关闭时机:一定要在所有异步查询完成后再调用connection.end(),否则会导致数据库连接提前关闭,查询失败。
  • 模板传值:用res.render()替代res.json(),才能把数据传给EJS模板进行渲染,而不是直接返回JSON接口。

内容的提问来源于stack exchange,提问作者Rodrigo Martins

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:20:18