NodeJS Finally块在Promise.all()完成之前运行

mwkjh3gx  于 2023-04-11  发布在  Node.js
关注(0)|答案(3)|浏览(177)

我正在编写一个脚本来播种我的数据库,但是在我的重建功能完成之前,我的node-pg连接被终止。

const rebuildDB = async () => {
  try {
    client.connect();
    await dropTables();
    await createTables();
    await Promise.all(employees.map(createEmployee), customers.map(createCustomer));
  } catch (err) {
    console.log(err);
  } finally {
    client.end();
  }
};

rebuildDB();

当我删除finally块时,一切都正常运行。如果我离开它,createEmployee函数将执行,但连接将在createCustomer()能够执行之前终止。
有什么建议吗?

ipakzgxi

ipakzgxi1#

  • 重新发布我的评论作为一个适当的答案(并添加到它):*

这里有两个问题。最主要的一个,也就是你问的,是你错误地调用了Promise.all。它只接受一个单个参数,而不是多个参数,所以它完全忽略了第二个参数的promise。你想传入一个 * 单个 * iterable(在本例中可能是一个数组)。
另一个问题是,您不希望client.connect()位于try内部,因为您不希望在client.connect()抛出时调用client.end()
所以:

const rebuildDB = async () => {
    // This shouldn't be *inside* the `try`, since you don't want to call
    // `client.end()` if this fails
    client.connect();  // <=== Does this need an await? It doesn't have one in your question...
    try {
        await dropTables();
        await createTables();
        // Pass a single array to `Promise.all`
        await Promise.all([...employees.map(createEmployee), ...customers.map(createCustomer)]);
    } catch (err) {
        console.log(err);
    } finally {
        client.end();
    }
};

rebuildDB();
mpbci0fu

mpbci0fu2#

@T.J Crowders的回答非常完美。我已经替换了

await Promise.all(employees.map(createEmployee), customers.map(createCustomer));

await Promise.all([...employees.map(createEmployee), ...customers.map(createCustomer)])
iklwldmw

iklwldmw3#

您可以将两个promises数组连接起来,以获得一个预期的可迭代参数

await Promise.all(
  employees.map(createEmployee)
    .concat(
      customers.map(createCustomer)
    )
);

这与其他答案中给出的spread操作符在结果方面是等效的。但是,如果你的数组非常大(我假设它们可能是来自一个db的所有条目),spread操作符可能会抛出Maximum call stack size exceeded错误。Concat在大型数组上更有效,特别是当你只有两个数组要合并时。
https://www.educative.io/answers/spread-operator-vs-arrayprototypeconcat-in-javascript上阅读更多信息

相关问题