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

Hapi结合PostgreSQL开发时pg client.query外部变量未更新如何解决

问题根因

你代码的核心问题是异步执行顺序错误:client.query是异步方法,不会阻塞后续代码执行,路由 handler 会在数据库查询完成前就执行回调外的return h.view,此时finalTable还是初始空字符串,回调内的返回值不会被路由捕获,自然没有数据。

修复方案

Hapi 原生支持 handler 用 async/await 处理异步逻辑,调整代码如下:

method: 'GET',
path: '/report',
// TODO Process data from DB into preformat text & table view
handler: async (request, h) => {
    const currentWeek = new Date().getWeek()
    // 改用参数化查询,避免SQL注入风险
    const getReport = `SELECT * FROM main_assignment WHERE week = $1`
    let finalTable = ''

    try {
        // 等待数据库查询完成再执行后续逻辑
        const queryRes = await client.query(getReport, [currentWeek - 1])
        // 用map简化数组拼接逻辑
        finalTable = queryRes.rows.map(element => `
            <tr>
                <td>${element.id}</td>
                <td>${element.name}</td>
                <td>${element.assignment}</td>
            </tr>`
        ).join('')
    } catch (err) {
        // 可自行添加查询错误的处理逻辑
        console.error('数据库查询失败:', err)
    }

    return h.view('report', {
        finalTable
    })
}

优化建议

  1. 不用在后端拼接HTML字符串,可直接把查询得到的queryRes.rows传递给模板引擎,在模板文件中用循环语法渲染表格行,逻辑更清晰也更易维护。以常用的Nunjucks模板为例,模板代码可以写成:
<table>
  <thead>
    <tr>
      <th>ID</th>
      <th>姓名</th>
      <th>作业内容</th>
    </tr>
  </thead>
  <tbody>
    {% for item in rows %}
    <tr>
      <td>{{ item.id }}</td>
      <td>{{ item.name }}</td>
      <td>{{ item.assignment }}</td>
    </tr>
    {% endfor %}
  </tbody>
</table>

对应的handler只需要传递rows参数即可:

return h.view('report', { rows: queryRes.rows })
  1. 不要在每次请求路由时调用client.connect(),pg客户端建议全局初始化连接池复用连接,避免频繁创建销毁连接带来的性能损耗。
  2. 新增的try/catch逻辑可以捕获数据库查询的异常,避免服务无响应崩溃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.19 18:15:11