Node.js中如何从promisify后的sqlite3 run方法获取插入ID或受影响行数?
解决sqlite3 promisify后run方法无法获取lastID/changes的问题
可以做到,无需额外封装包。核心问题是util.promisify默认只处理回调的参数,而sqlite3的run方法把lastID和changes挂在回调的this上下文中,而非回调参数里。下面提供两种原生实现方案:
方案一:手动封装Promise版本的run方法
直接写一个函数,将db.run的回调逻辑包装成Promise,在回调中提取this上的lastID和changes:
const sqlite3 = require('sqlite3').verbose(); const db = new sqlite3.Database(':memory:'); function runAsync(db, sql, params = []) { return new Promise((resolve, reject) => { db.run(sql, params, function(err) { if (err) { reject(err); } else { // 从回调的this中提取所需数据 resolve({ lastID: this.lastID, changes: this.changes }); } }); }); } // 使用示例 async function demo() { // 创建表 await runAsync(db, 'CREATE TABLE users (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT)'); // 插入数据并获取结果 const insertResult = await runAsync(db, 'INSERT INTO users (name) VALUES (?)', ['Alice']); console.log('插入ID:', insertResult.lastID); // 输出 1 console.log('受影响行数:', insertResult.changes); // 输出 1 // 更新数据 const updateResult = await runAsync(db, 'UPDATE users SET name = ? WHERE id = ?', ['Alicia', 1]); console.log('更新受影响行数:', updateResult.changes); // 输出 1 } demo().catch(err => console.error(err));
方案二:自定义util.promisify的行为
利用util.promisify.custom属性,给db.run定制Promise化的逻辑,这样后续可以直接用util.promisify生成异步方法:
const sqlite3 = require('sqlite3').verbose(); const util = require('util'); const db = new sqlite3.Database(':memory:'); // 给db.run添加自定义promisify逻辑 db.run[util.promisify.custom] = function(sql, params) { return new Promise((resolve, reject) => { this.run(sql, params, function(err) { if (err) { reject(err); } else { resolve({ lastID: this.lastID, changes: this.changes }); } }); }); }; // 生成promisify后的run方法 const runAsync = util.promisify(db.run); // 使用示例 async function demo() { await runAsync('CREATE TABLE products (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT)'); const result = await runAsync('INSERT INTO products (name) VALUES (?)', ['Laptop']); console.log('插入ID:', result.lastID); // 输出 1 } demo().catch(err => console.error(err));
两种方案都完全基于原生sqlite3和util包,不需要引入额外依赖,核心都是在Promise的resolve阶段,从run方法回调的this上下文里提取lastID和changes并返回。
内容的提问来源于stack exchange,提问作者HimmDawg
相关产品推荐
相关产品推荐

