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); }); }); }
二、工具选择建议
关于better-sqlite3 vs 原sqlite3
better-sqlite3的同步API更适合个人小型应用,代码逻辑直观,不用处理复杂的异步回调嵌套,开发效率更高。而且它完全支持TypeScript(安装@types/better-sqlite3即可获得类型提示),没必要换成纯JS,继续用TypeScript+better-sqlite3反而能保留类型安全的优势。是否需要更换数据库框架
个人看板应用的场景下,SQLite完全够用——轻量、无需额外部署数据库服务、读写性能足以支撑个人使用。除非你后续打算把应用扩展成多人协作的大型服务,否则暂时不需要更换PostgreSQL、MySQL这类数据库。
内容的提问来源于stack exchange,提问作者LimoNade95
相关产品推荐
相关产品推荐

