节点 |异步主线程需要几秒钟才能完成

nodejs | async main thread takes a few seconds to finish

我有一个小的 nodejs 脚本,它 运行 使用 pg-promise 对数据库进行异步查询,但由于某种原因,脚本 在完成前挂了几秒钟 (即,在我重新访问终端之前)。 为什么会这样?这不是什么大问题,但我不明白为什么主线程会挂几秒钟。

密码是:

import pgpPackage from 'pg-promise';
const pgp = pgpPackage();

const env = {
  dbUrl: process.env.DB_URL
};

const app = {
  db: pgp(env.dbUrl),
};

const main = async () => {
  console.log(await app.db.any('select 1'));
  return 42;
};

try {
  const x = await main();
  console.log('all ok, main returned', x);
} catch (err) {
  console.log('an error occurred:', err);
};

我得到的是:

>> DB_URL=postgres://postgres:postgres1234@localhost:5432/panaderias node index.js
[ { '?column?': 1 } ]
all ok, main returned 42
 <--- At this point it hangs for ~10 seconds and then it finishes without issues

供参考,

>> node --version
v16.1.0

数据库 运行 正在 docker 容器中,但这不应该是相关的。


如果我替换

  console.log(await app.db.any('select 1'));

  console.log(await 1);

然后脚本立即结束。


问题是为什么脚本需要几秒钟才能完成。我的猜测是一些承诺悬而未决,但我无法弄清楚发生了什么。

我猜想数据库正在使用一些计时器来保持 nodejs 进程 运行 直到计时器停止。也许如果您明确关闭数据库或不会发生的连接池。或者,您可以将数据库配置为使用更短的计时器。

而且,正如您所报告的:

app.db.$pool.end();

将停止延迟。

pg-promise 基于连接池的使用,连接池兑现实时连接,以提供快速响应。

池的默认配置允许实时连接在释放之前闲置 30 秒(可配置)。

编写直通应用程序时,通常会添加手动池终止,以强制立即释放所有连接,并退出进程...

释放一个特定池:

db.$pool.end();

释放进程中的所有池:

pgp.end();

It is documented in the library, and shown in the examples.

更新

从 pg-promise v10.11.0,您不再需要显式关闭池。相反,您可以只设置连接选项 allowExitOnIdle: true,让进程在池空闲时退出。