【问题标题】:Same promises gives two different results相同的承诺会产生两种不同的结果
【发布时间】:2018-11-06 16:32:49
【问题描述】:

大家早上好。

我一直在研究一个给我带来问题的函数。

.then(function (values2) {
  function generateReports () {

    return Promise.all([
        Reports.InterCompaniesUsa                   .generate(periodToClose.date_start, periodToClose.date_end, {save: true}),
        Reports.InterCompaniesCanada                .generate(periodToClose.date_start, periodToClose.date_end, {save: true}),
        Reports.Design                              .generate(periodToClose.date_start, periodToClose.date_end, {save: true}),
        Reports.Production                          .generate(periodToClose.date_start, periodToClose.date_end, {save: true}),

        Reports.MonthlySalesByCustomers             .generate(periodToClose.date_start, periodToClose.date_end, {save: true}),
        Reports.Cashing                             .generate(periodToClose.date_start, periodToClose.date_end, {save: true}),
        Reports.Income                              .generate(periodToClose.date_start, periodToClose.date_end, {save: true}),
        Reports.AgedTrialBalance                    .generate(periodToClose.date_start, periodToClose.date_end, {save: true})
    ])
  }

  function generateAllAccountStatement () {
    db.select('invoices.customer_id_customer')
      .distinct('invoices.customer_id_customer')
      .from('invoices')
      .where({
        'invoices.invoice_status': 'INVOICED'
      })
      .andWhere(function () {
        this.where('invoices.invoice_date', '<=', periodToClose.date_end)
          .andWhere('invoices.invoice_date', '>=', periodToClose.date_start)
      })
      .orWhere(function () {
        this.where('invoices.invoice_date', '<=', periodToClose.date_start)
          .andWhere('invoices.balance', '<>', 0)
      })
      .then(function (arrOfCustomersWithInvoicesThisMonthOrWithPostponeBalance) {
        arrOfCustomersWithInvoicesThisMonthOrWithPostponeBalance.forEach(function (oneCustomer) {
          Reports.AccountStatement.generate(periodToClose.date_end, oneCustomer.customer_id_customer, {save: true});
        })
      })
      .catch(function (err) {
        console.error(err)
      })
  }

  return Promise.all([generateReports(), generateAllAccountStatement()])
})
.then(function (allIsDoneYes) {
  return res.json(allIsDoneYes);
})
.catch(function (err) {
  console.error(err);
  return res.status(500).send(err);
})

我的问题是:函数 generateReports 无法解析。我试图隔离其中的每个承诺,它们都很好。当我用下面的代码替换该函数时,它正在工作,我想知道为什么(因为它们在我看来几乎相同)。

function generateReports () {
    Promise.all([
        Reports.InterCompaniesUsa                   .generate(periodToClose.date_start, periodToClose.date_end, {save: true}),
        Reports.InterCompaniesCanada                .generate(periodToClose.date_start, periodToClose.date_end, {save: true}),
        Reports.Design                              .generate(periodToClose.date_start, periodToClose.date_end, {save: true}),
        Reports.Production                          .generate(periodToClose.date_start, periodToClose.date_end, {save: true}),

        Reports.MonthlySalesByCustomers             .generate(periodToClose.date_start, periodToClose.date_end, {save: true}),
        Reports.Cashing                             .generate(periodToClose.date_start, periodToClose.date_end, {save: true}),
        Reports.Income                              .generate(periodToClose.date_start, periodToClose.date_end, {save: true}),
        Reports.AgedTrialBalance                    .generate(periodToClose.date_start, periodToClose.date_end, {save: true})
    ])
    .then(result => {
        return result;
    })
    .catch(err => {
        console.error(err);
    })
}

【问题讨论】:

  • 你没有return来自generateAllAccountStatement的promise链...
  • @JonasWilms - 在generateAllAccountStatement 中不返回任何内容不太可能对generateReports 中的承诺产生影响
  • 事情是 generateAllAccountStatement 是异步的,但你永远不会等待它开始,更不用说完成了,除非你 return db.slecect .... 并在 arrOfCustomersWithInvoicesThisMonthOrWithPostponeBalance.forEach 中执行一系列承诺
  • 我还要在.then(function (allIsDoneYes) 之后添加一个.catch - 可能有错误
  • 是的。 generateAllAccountStatement 是异步的,我在这里不需要任何回报。在.then(function (allIsDoneYes) 之后已经有一个.catch。我编辑了问题。

标签: javascript promise bluebird knex.js


【解决方案1】:

可能是当你运行这么多并行时

Reports.*.generate(periodToClose.date_start, periodToClose.date_end, {save: true}),

并行查询,如果生成的代码有一些错误或奇怪的依赖关系,它们可能会填满您的池并阻塞整个应用程序。

尝试将 DEBUG=knex:* 环境变量添加到您的 shell 并运行您的报告生成代码:

await generateReports();

看看你是否能发现数据库连接有什么奇怪的地方,或者看看解决这个承诺的地方。

您也可以先尝试制作较小的 generateReports 实现,它只生成一个报告,然后向其中添加更多报告,直到找到 promise 不再解决的组合。

【讨论】:

    猜你喜欢
    • 2022-01-26
    • 2022-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多