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

TypeScript+SQLite3查询返回空数组问题及技术选型咨询

问题解决与工具选择建议

一、异步返回空数组的原因及解决办法

你遇到的问题核心是异步回调的执行时机没处理对:db.each是异步遍历方法,如果你在遍历还没完成时就resolve结果数组,数组自然是空的,但遍历过程里的console.log能正常打印每一行数据,说明查询本身是能拿到数据的。

错误写法示例(导致空数组)

function getBoardNames() {
  return new Promise((resolve) => {
    const names: string[] = [];
    // each是异步遍历,回调会在每一行数据返回时执行
    db.each('SELECT name FROM board ORDER BY position', (err, row) => {
      if (err) throw err;
      console.log(row['name']); // 能打印数据
      names.push(row['name']);
    });
    // 遍历还没完成就resolve,此时names是空数组
    resolve(names);
  });
}

正确写法1:利用each的完成回调

db.each的第三个参数是遍历完成后的回调,要在这个回调里resolve结果:

function getBoardNames() {
  return new Promise((resolve, reject) => {
    const names: string[] = [];
    db.each(
      'SELECT name FROM board ORDER BY position',
      (err, row) => {
        if (err) return reject(err);
        console.log(row['name']);
        names.push(row['name']);
      },
      // 遍历完成后执行,此时names已填充完毕
      (err, count) => {
        if (err) return reject(err);
        resolve(names);
      }
    );
  });
}

正确写法2:直接用db.all方法

db.all会一次性返回所有查询结果,无需手动遍历收集,代码更简洁:

function getBoardNames() {
  return new Promise((resolve, reject) => {
    db.all('SELECT name FROM board ORDER BY position', (err, rows) => {
      if (err) return reject(err);
      const names = rows.map(row => row['name']);
      resolve(names);
    });
  });
}

二、工具选择建议

  1. 关于better-sqlite3 vs 原sqlite3
    better-sqlite3的同步API更适合个人小型应用,代码逻辑直观,不用处理复杂的异步回调嵌套,开发效率更高。而且它完全支持TypeScript(安装@types/better-sqlite3即可获得类型提示),没必要换成纯JS,继续用TypeScript+better-sqlite3反而能保留类型安全的优势。

  2. 是否需要更换数据库框架
    个人看板应用的场景下,SQLite完全够用——轻量、无需额外部署数据库服务、读写性能足以支撑个人使用。除非你后续打算把应用扩展成多人协作的大型服务,否则暂时不需要更换PostgreSQL、MySQL这类数据库。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 09:30:21