为什么要使用batch()代替Promise.all?

问题描述 投票:1回答:2

从pg-promise常见问题Why use method batch instead of promise.all?

在释放连接之前,解决您在任务或事务中创建的所有promise-queries是非常典型的

我不明白为什么这应该是一个问题。

对于example,当我们有这样的查询数组时:

  [
    t.any("SELECT pg_sleep(2) as a"),
    t.any('this will fail'),
    t.any("SELECT pg_sleep(3) as b")
  ]

注意:pg_sleep仅用于测试。在生产中,这将是Insert/Update/Delete语句。而且,我们只想在全部成功后才提交事务:即当其中任何一个失败时都返回错误。

当我们使用batch()

  • 第一个承诺将在2秒后解决
  • 第二个承诺将拒绝
  • 第三个查询仍将发送到数据库,并在3秒后返回
  • 最后(总共5秒钟之后),完成batch,我们可以将错误返回给调用方。

当我们使用Promise.all()

  • 第一个承诺将在2秒后解决
  • 第二个承诺将拒绝-这将回滚事务并释放数据库连接
  • 现在我们已经可以向调用者返回错误
  • 第三个请求将立即失败,并显示Querying against a released or lost connection.。无论如何,这是预期的,因此我们可以忽略它。

所以我想说Promise.all更好,因为:

  • 它在第一个错误之后立即返回
  • 甚至都不会将第三个无用的查询发送到数据库

我想念什么?这是否会导致其他问题:例如断开的连接返回到池中,等等。

pg-promise
2个回答
1
投票
方法batch适用于可能创建动态查询数量的情况。

它确保所有查询都已解决(解决或拒绝),因此您不会最终针对封闭的连接执行查询,并得到Querying against a released or lost connection错误。开始让那些错误发生在上下文之外可能会很糟糕/令人困惑,并且您无法诊断正在发生的事情。

方法Promise.all不履行承诺,它停止处理并在数组中的第一个承诺拒绝时拒绝。

尽管方法batch仍然非常有用,因为它在处理值方面更加灵活,并且比Promise.all提供更好的结果/错误详细信息,但今天不再需要使用它。它是在async/await不存在的ES5时代开发的。但是今天您可以轻松地将其替换为async/await

旧样式:

db.task('get-all-records', t => { return t.batch([ t.any('SELECT * FROM apples'), t.any('SELECT * FROM oranges') ]); }) .then([apples, oranges] => { // process data here }) .catch(error => {});

新样式:

db.task('get-all-records', async t => { const apples = await t.any('SELECT * FROM apples'); const oranges = await t.any('SELECT * FROM oranges'); return {apples, oranges}; }) .then({apples, oranges} => { // process data here }) .catch(error => {});

上面两个示例的结果将是相同的,尽管它们在执行逻辑上是不同的,因为第一个是完全异步的,而后一个使用了阻塞操作的async/await,它们会阻止您如果创建前一个查询失败,甚至无法创建下一个查询。

0
投票
vitaly-t's answer很棒。对于我的特殊用例,请再考虑一下:执行多个查询,并在第一个查询失败时停止-不需要结果

我认为最好更改逻辑,以便我们不要构建一个Promise数组,而是构建一个查询字符串数组(当查询需要参数时使用format())。然后等待所有的人:

db.task(async t => { const queries = [ "SELECT pg_sleep(2) as a", 'this will fail', "SELECT pg_sleep(3) as b" ]; for (const q of queries) await t.any(q); });

这种方式:

    该函数将在发生错误时立即抛出
  • 剩余的查询将不会执行
  • 我们没有得到令人困惑的Querying against a released or lost connection错误
© www.soinside.com 2019 - 2024. All rights reserved.