“Finally block is running before Promise.all() finished.”

huangapple go评论118阅读模式
英文:

Finally block is running before Promise.all() finished

问题

以下是代码的翻译部分:

我正在编写一个用于填充我的数据库的脚本但在重建函数完成之前我的 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() 能够执行之前连接将被终止。

有任何建议吗?

英文:

I'm working on a script to seed my database but am having issues with my node-pg connection being terminated before my rebuild function is finished.

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();

When I remove the finally block everything runs correctly. If i leave it, the createEmployee function will execute but the connection will be terminated before createCustomer() is able to execute.

Any suggestions?

答案1

得分: 1

以下是您要翻译的部分:

"Reposting my comment as a proper answer (and adding to it):

There are two issues. The main one, which you asked about, is that you're calling Promise.all incorrectly. It accepts only a single argument, not multiple arguments, so it's ignoring the promises from the second argument entirely. You want to pass in a single iterable (probably an array in this case).

The other problem is that you don't want client.connect() inside the try, since you don't want to call client.end() if client.connect() throws.

So:

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();
英文:

Reposting my comment as a proper answer (and adding to it):

There are two issues. The main one, which you asked about, is that you're calling Promise.all incorrectly. It accepts only a single argument, not multiple arguments, so it's ignoring the promises from the second argument entirely. You want to pass in a single iterable (probably an array in this case).

The other problem is that you don't want client.connect() inside the try, since you don't want to call client.end() if client.connect() throws.

So:

const rebuildDB = async () =&gt; {
    // This shouldn&#39;t be *inside* the `try`, since you don&#39;t want to call
    // `client.end()` if this fails
    client.connect();  // &lt;=== Does this need an await? It doesn&#39;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();

答案2

得分: 0

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

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

这在结果上等同于其他答案中提到的展开运算符。然而,如果你的数组非常大(我假设它们可能是从数据库中获取的所有条目),展开运算符可能会引发Maximum call stack size exceeded错误。对于大数组,特别是如果你只有两个数组要合并,使用concat 更有效率。

了解更多信息,请访问 https://www.educative.io/answers/spread-operator-vs-arrayprototypeconcat-in-javascript

英文:

You can concat your two promises arrays in order to have the one expected iterable argument

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

This is equivalent in terms of result with the spread operator given in other answers. However if your arrays are very large (and I assume they could be if they are all the entries from a db) the spread operator could throw a Maximum call stack size exceeded error. Concat is more efficient on large arrays, especially if you only have two arrays to merge.

Read more about this on https://www.educative.io/answers/spread-operator-vs-arrayprototypeconcat-in-javascript

huangapple
  • 本文由 发表于 2023年4月7日 00:28:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/75951741.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定