【问题标题】:nodejs | async main thread takes a few seconds to finish节点 |异步主线程需要几秒钟才能完成
【发布时间】:2021-09-10 08:44:51
【问题描述】:

我有一个小的 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();`以及它如何正确结束
  • 我在我的答案中添加了一个更新部分;)

标签: node.js async-await pg-promise


【解决方案1】:

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

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

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

发布一个特定的池:

db.$pool.end();

释放进程中的所有池:

pgp.end();

It is documented in the libraryshown in the examples

更新

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

【讨论】:

    【解决方案2】:

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

    而且,正如您所报告的:

    app.db.$pool.end();
    

    将停止延迟。

    【讨论】:

    • 这不再需要,请参阅我的答案中的更新部分。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-25
    • 2013-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多