使用Knex.js查询PostgreSQL后Node.js程序挂起无法退出的解决方法咨询
解决Knex.js查询PostgreSQL后Node.js进程挂起无法退出的问题
问题代码
const knex = require('knex'); db = knex({ client: 'pg', connection: `connectionString` }) db.raw(` select * from tablename; `).then((resp) => { console.log(resp.rows); resp.rows.forEach((element => { console.log(element) })) })
问题原因
Knex默认会维护一个数据库连接池,即便查询逻辑执行完毕,连接池仍会保持活跃连接,导致Node.js事件循环无法清空,进程因此挂起不退出。
你之前尝试的.then(process.exit())写法错误——process.exit()会被立即执行,而非等待Promise完成后触发,所以进程提前终止,没来得及完成查询操作。
解决方案
方案1:关闭连接池让进程自动退出(推荐)
在Promise链的finally块中调用db.destroy()关闭连接池,释放所有数据库连接,此时事件循环无活跃任务,进程会自动干净退出:
const knex = require('knex'); // 用const声明db,避免全局变量泄漏 const db = knex({ client: 'pg', connection: `connectionString` }) db.raw(`select * from tablename;`) .then((resp) => { console.log(resp.rows); resp.rows.forEach(element => { console.log(element); }); }) .finally(() => { // 无论查询成功或失败,都关闭连接池 return db.destroy(); });
方案2:手动控制进程退出
如果需要明确控制退出时机,需将process.exit()包装成回调函数,且必须先关闭连接池再退出:
const knex = require('knex'); const db = knex({ client: 'pg', connection: `connectionString` }) db.raw(`select * from tablename;`) .then((resp) => { console.log(resp.rows); resp.rows.forEach(element => { console.log(element); }); }) .then(() => db.destroy()) .then(() => process.exit(0)) // 0表示正常退出 .catch((err) => { console.error('查询出错:', err); db.destroy(); process.exit(1); // 非0表示错误退出 });
关键注意点
- 不要直接在
.then中传递process.exit(),必须写成.then(() => process.exit()),否则函数会立即执行。 - 优先使用
db.destroy()让进程自动退出,避免强制退出可能导致的资源泄漏。
内容的提问来源于stack exchange,提问作者Matt
相关产品推荐
相关产品推荐

