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

Express+SQLite3首次请求无数据需刷新,如何解决?

问题描述

使用Express框架搭配SQLite及SQLite3模块开发时,启动服务器后首次请求无法加载数据,必须刷新页面才能显示。尝试将db.each()包装为Promise并等待执行完成后渲染页面,但未生效,且仅使用SQLite3,不考虑SQLite3-express。

错误原因分析

  1. db.each()异步处理逻辑错误:db.each()是异步方法,当前代码在调用后立即resolve(rows),此时遍历还未完成,首次请求时rows只有初始值;刷新时因全局rows已缓存之前的数据,所以能显示。
  2. 全局变量rows导致数据污染:rows定义在全局作用域,每次查询都会追加数据,多次请求后数据重复。
  3. 重复创建数据库连接:每次调用query都新建连接,既低效又可能引发连接泄漏。
  4. getMultiple()无返回值:该函数使用await但未返回结果,导致路由中res.json()接收的是undefined。

修正后的代码

db.js

const sqlite3 = require('sqlite3').verbose();
const path = "C:/Users/Administrateur.DESKTOP-OQRUHSR/Desktop/sqlite-tools-win32-x86-3410000/db/test.db";

// 全局创建一次数据库连接,避免重复初始化
const db = new sqlite3.Database(path, (err) => {
  if (err) {
    console.error("数据库连接失败:", err.message);
  } else {
    console.log("数据库连接成功");
  }
});

function query(sql) {
  return new Promise((resolve, reject) => {
    const rows = [];
    db.each(sql, (err, row) => {
      if (err) {
        console.error(err.message);
        reject(err); // 捕获行处理错误并reject
        return;
      }
      rows.push(row);
      console.log(row.id, row.name);
    }, (err, count) => {
      // 遍历完成的回调,所有行处理完毕后执行
      if (err) {
        reject(err);
      } else {
        console.log(`共查询到${count}条数据`);
        resolve(rows);
      }
    });
  });
}

module.exports = { query };

prog.js

const db = require('./db');

async function getMultiple() {
  // 返回查询结果,确保上层能获取到数据
  return await db.query("SELECT id, name FROM users");
}

module.exports = { getMultiple };

routes.js

const express = require('express');
const router = express.Router();
const programmingLanguages = require('../services/prog');

router.get('/', async function (req, res, next) {
  try {
    const data = await programmingLanguages.getMultiple();
    res.json(data);
  } catch (err) {
    console.error(`获取数据时出错:`, err.message);
    next(err);
  }
});

module.exports = router;

关键修正说明

  • 正确处理db.each()异步流程:利用db.each()的第三个完成回调,确保所有行遍历完成后再resolve Promise,保证数据完整。
  • 移除全局rows变量:每次查询创建局部数组,避免数据污染。
  • 复用数据库连接:全局初始化一次连接,提升性能并避免连接泄漏。
  • 完善错误处理:在db.each()的行处理和完成回调中捕获错误,通过reject抛出,便于上层统一处理。
  • 确保函数返回值:getMultiple()返回查询结果,让路由能正确响应数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 05:35:20