Jest TLSWRAP 使用简单的 node-postgres pool.query() 修复了 setTimeout 延迟的打开句柄错误,但为什么呢?

Jim*_*ode 5 node.js express node-postgres jestjs

当我运行以下测试时:

afterAll(async () => {
    await runDbBuild();
    await pool.end();
});

describe("queries.newteetypes.select.all():", () => {
        test("Test 1: object keys ", async () => {
            const awaitedResponse = await queries.newteetypes.select.all();
            expect(awaitedResponse).toStrictEqual(anticipatedResponse);
    });
});
Run Code Online (Sandbox Code Playgroud)

我收到此错误:Jest has detected the following 1 open handle potentially keeping Jest from exiting: 错误截图

上面显示的代码在生产中工作得非常好。问题只是jest给我一个潜在的打开句柄警告。

setTimeout()我可以通过使用和引入延迟来修复它Promise,但放置位置让我感到困惑。这是解决方案(相同的代码,但在查询调用上方添加了一行):

afterAll(async () => {
    await runDbBuild();
    await pool.end();
});

describe("queries.newteetypes.select.all():", () => {
        test("Test 1: object keys ", async () => {
            await new Promise((resolve) => setTimeout(() => resolve(), 2000)); // Putting a delay before the query solves the problem, but putting the delay after the query doesn't resolve it.
            const awaitedResponse = await queries.newteetypes.select.all();
            expect(awaitedResponse).toStrictEqual(anticipatedResponse);
    });
});
Run Code Online (Sandbox Code Playgroud)

这对我来说似乎非常违反直觉。最初,我尝试将超时放入函数中afterAll(),但无论我将其包含在何处,都没有任何区别。因此,我尝试将其放在函数内的查询调用之后test(),但这不起作用。当我将其放在查询调用之前时,我不再收到错误。但为什么这会有所不同呢?

alf*_*ema 7

将您的“new Pool(...)”视为承诺并await为此:

async function createPool () {
  return await new Pool({ connectionString })
}
Run Code Online (Sandbox Code Playgroud)

你的发现setTimeout让我尝试了同样的成功结果:

await process.nextTick(() => {})
Run Code Online (Sandbox Code Playgroud)

把它放在我connect()工作之前。因此,从那里我开始支持“最早”的观点,即添加 aprocess.nextTick可以解决问题,并且似乎只需将其视为new Pool(..)承诺即可解决。

也许矿池愿意在完全准备好在幕后追踪客户之前就开始分发客户?这可能就是为什么额外的await前期费用可以解决这个问题。

这可能与人们无法正确关闭客户端或池的原因有很大关系——因为池管理的某些内容被破坏了。例如:https: //github.com/brianc/node-postgres/issues/2341