【问题标题】:Do I need to await for each nested array of promises?我需要等待每个嵌套的承诺数组吗?
【发布时间】:2019-09-28 05:21:26
【问题描述】:

在下面的代码中,我为每个异步函数使用了await Promise.all,然后最终返回一个值。所以我想问一下:是否有必要为每个异步函数使用await Promise.all,还是一个等待(放在最后)await Promise.all 来完成这项工作?

async sendEmailNotifications() {
  const users = await User.find({  })
  const promises = users.map(async(user) => {
    const _promises = user.appId.map(async(app) => {
      const myApp = await App.findOne({ _id: app })
      if (myApp) {
        const sendNotification = await emailService.analyticsNotification(emailObj)
      }
    })
    await Promise.all(_promises)
  })
  await Promise.all(promises)
  return 'done'
}

【问题讨论】:

  • 您没有在 .map 函数中返回任何内容。
  • @AshishKumar 我不想从.map 返回任何东西。我只想等到我的地图功能完成。
  • @AshishKumar .map 在这里很有用,因为他使用异步函数,自动返回 Promises,他想等待所有 Promises 完成。
  • 如果您感兴趣的是所有承诺是否已完成,答案是否定的,您可以只使用一个Promise.all,查看您的代码我看不到内部循环中将返回的任何内容外部的任何东西,所以等待内部的Promise.all 不会得到任何东西。但是说到这里,我认为无论如何使用 2 可能会更好,这取决于每个 map 中有多少,因为一个 Promise.all 中的太多可能会导致抖动,这是一个并发映射会更好。您的 2 promise.all 在这里可能仍然存在抖动问题,也许外部可能会更好作为for of

标签: javascript node.js asynchronous promise


【解决方案1】:

是的,Promise.alls 对于您当前的实施都是必需的。异步函数返回一个 Promise。如果该函数内没有awaits,并且该函数没有显式返回 Promise,则 Promise 将立即解析。所以,没有

await Promise.all(_promises)

return Promise.all(_promises)

,您的const promises = users.map 数组将产生一系列承诺,所有承诺都会立即解决。您需要内部 Promise.all 才能使整个 sendEmailNotifications 函数的 Promise 仅在所有 .findOnes 和 analyticsNotifications 完成后才解析。

请记住,在您当前的代码中,所有请求都是一次性发出的;没有迭代取决于最后一次迭代的 Promise 首先完成,如果那是你担心的。唯一的代码阻塞行为是在

  const myApp = await App.findOne({ _id: app })
  if (myApp) {
    const sendNotification = await emailService.analyticsNotification(emailObj)
  }

.findOne 必须在 analyticsNotification 运行之前解析,但该逻辑看起来是必需的,并且没有办法绕过它。

我想技术上可能将您的代码更改为一个巨大的 Promise 数组,您在 一次上调用 Promise.all,每个 user.appId item 被转换为 Promise 并推送到外部数组,但这功能较少,导致代码更丑陋,并且没有任何好处,IMO。

【讨论】:

  • 非常感谢....findOne 在analyticsNotification 运行之前必须解决的问题 为什么?我确实检查了这一点,并且大多数时候它等到我的analyticsNotification 函数返回值。你认为这里有什么问题?您认为它会跳出if 条件并且可能会失败吗?
  • 我只是假设因为您当前的逻辑取决于它。您需要知道myApp 的真实性,以便知道您是否需要运行analyticsNotification。这不是问题,没有什么问题,只是需要的逻辑(对吧?)
  • 这也是我很想知道的。是否在 if 条件内等待下面的代码。还是只是执行它?好吧,我也对此进行了测试,并且它可以工作,但是当我不应该本能时。我说的对吗?
  • 是的,await 将阻止同一函数中的以下代码运行。
  • await(等待单个 Promise 解析)是 Promise.prototype.then 的替代品 - Promise.all 完全不同(它等待数组中的每个 Promise 解析)。在性能方面,问题中的任何代码都绝对没有问题 - 我不会改变它。
猜你喜欢
  • 2018-04-17
  • 1970-01-01
  • 2020-04-21
  • 1970-01-01
  • 1970-01-01
  • 2018-05-05
  • 2017-04-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多