【问题标题】:Enhance performance on multiple promises提高多个承诺的性能
【发布时间】:2020-06-08 07:25:18
【问题描述】:

所以,我有一堆承诺,我需要将它们存储在不同的变量中,然后这些变量将成为不同对象键的值,该对象将返回给 API 并提供给用户。

我面临的问题是它很慢(在 150 毫秒到 1000 毫秒之间)。

有没有更好的方法可以更快地兑现所有这些承诺?或者只是避免它们?不能使用 Promise.all(),因为所有值都必须存储在不同的变量中。

  const scheduledTotalExVat = await calculateFieldTotal(scheduledMilestones, 'totalPriceExVat');
  const scheduledTotalIncVat = await calculateFieldTotal(scheduledMilestones, 'totalPriceIncVat');
  const achievedTotalExVat = await calculateFieldTotal(achievedMilestones, 'totalPriceExVat');
  const achievedTotalIncVat = await calculateFieldTotal(achievedMilestones, 'totalPriceIncVat');
  const invoicedTotalExVat = await calculateFieldTotal(invoicedMilestones, 'totalPriceExVat');
  const invoicedTotalIncVat = await calculateFieldTotal(invoicedMilestones, 'totalPriceIncVat');
  const paidTotal = await calculateFieldTotal(paidMilestones, 'amountPaid');
  const totalExVat = await calculateFieldTotal(allMilestones, 'totalPriceExVat');
  const totalIncVat = await calculateFieldTotal(allMilestones, 'totalPriceIncVat');
  const quotationTotalExVat = await calculateFieldTotal(projectQuotations, 'totalPriceExVat');
  const quotationTotalIncVat = await calculateFieldTotal(projectQuotations, 'totalPriceIncVat');

  const summary = {
    milestonesScheduledExVat: scheduledTotalExVat,
    milestonesScheduledIncVat: scheduledTotalIncVat,
    milestonesAchievedExVat: achievedTotalExVat,
    milestonesAchievedIncVat: achievedTotalIncVat,
    milestonesInvoicedExVat: invoicedTotalExVat,
    milestonesInvoicedIncVat: invoicedTotalIncVat,
    milestonesPaid: paidTotal,
    milestonesTotalExVat: totalExVat,
    milestonesTotalIncVat: totalIncVat,
    unbilledTotalExVat: quotationTotalExVat - paidTotal,
    unbilledTotalIncVat: quotationTotalIncVat - paidTotal,
  };

  return summary;

calculateFieldTotal() 函数只不过是一个简短的代码,用于循环遍历对象数组并将特定字段的值相加。

  async function calculateFieldTotal(arrayOfObjects, fieldToCalculate) {
  if (!arrayOfObjects || !fieldToCalculate) {
    throw new Error('Missing fields for calculation.');
  }

  return (
    arrayOfObjects
      .map(obj => parseFloat(obj[fieldToCalculate]))
      .reduce((acc, current) => acc + current, 0) || 0
  );
}

我不太喜欢它的外观,但我找不到更可扩展或更漂亮的方法。

提前致谢。

【问题讨论】:

  • .map.reduce 的本质是同步的,为什么要为它们使用 asyncawait
  • 如果我不这样做,则这些值无效。但即使这样仍然很慢。
  • 哪些值无效?你能给我们举个例子吗,也许是minimal reproducible example?此外,当解析时,promise.all() 返回一个数组,其中每个值都是每个调用的承诺/函数的结果...
  • Can't use Promise.all(), values have to be stored in different variables. 这不是Promise.all的限制
  • calculateFieldTotal() 不是异步的。返回值不需要是async,也不需要是await

标签: javascript arrays performance object promise


【解决方案1】:

您可以使用Promise.all 并将结果存储在不同的变量中:

const [
  scheduledTotalExVat,
  scheduledTotalIncVat,
  achievedTotalExVat,
  achievedTotalIncVat,
  invoicedTotalExVat,
  invoicedTotalIncVat,
  paidTotal,
  totalExVat,
  totalIncVat,
  quotationTotalExVat,
  quotationTotalIncVat
] = await Promise.all([
  calculateFieldTotal(scheduledMilestones, "totalPriceExVat"),
  calculateFieldTotal(scheduledMilestones, "totalPriceIncVat"),
  calculateFieldTotal(achievedMilestones, "totalPriceExVat"),
  calculateFieldTotal(achievedMilestones, "totalPriceIncVat"),
  calculateFieldTotal(invoicedMilestones, "totalPriceExVat"),
  calculateFieldTotal(invoicedMilestones, "totalPriceIncVat"),
  calculateFieldTotal(paidMilestones, "amountPaid"),
  calculateFieldTotal(allMilestones, "totalPriceExVat"),
  calculateFieldTotal(allMilestones, "totalPriceIncVat"),
  calculateFieldTotal(projectQuotations, "totalPriceExVat"),
  calculateFieldTotal(projectQuotations, "totalPriceIncVat")
]);

const summary = {
  milestonesScheduledExVat: scheduledTotalExVat,
  milestonesScheduledIncVat: scheduledTotalIncVat,
  milestonesAchievedExVat: achievedTotalExVat,
  milestonesAchievedIncVat: achievedTotalIncVat,
  milestonesInvoicedExVat: invoicedTotalExVat,
  milestonesInvoicedIncVat: invoicedTotalIncVat,
  milestonesPaid: paidTotal,
  milestonesTotalExVat: totalExVat,
  milestonesTotalIncVat: totalIncVat,
  unbilledTotalExVat: quotationTotalExVat - paidTotal,
  unbilledTotalIncVat: quotationTotalIncVat - paidTotal
};

return summary;

【讨论】:

  • 感谢您,但是,响应初始 cmets 并不能解决性能问题。
  • @Scarecrowsama 那么性能问题不是您显示的代码。 calculateFieldTotal 是瓶颈。
  • 之前有一个很简单的sequelize查询,不过应该不会花那么长时间,挺简单的。
  • @Scarecrowsama 有一种直觉,它可能比你想象的要花更长的时间 :),因为查询很简单并不总是意味着它很快,没有合适的索引等看起来很简单的东西通常是性能瓶颈的根本原因。
  • @Scarecrowsama 尝试测量这些查询所花费的时间,(检查您是否在每次查询时打开/关闭数据库连接)
猜你喜欢
  • 1970-01-01
  • 2016-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多