Нужно ли ждать каждого вложенного массива обещаний? - PullRequest
4 голосов
/ 10 мая 2019

В приведенном ниже коде я использовал 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'
}

1 Ответ

3 голосов
/ 10 мая 2019

Да, оба Promise.all необходимы для вашей текущей реализации.Асинхронная функция возвращает Promise.Если в этой функции нет await s, и эта функция явно не возвращает Обещание, Обещание будет выполнено немедленно.Таким образом, без

await Promise.all(_promises)

или

return Promise.all(_promises)

ваш массив const promises = users.map приведет к массиву обещаний, которые все разрешаются немедленно.Внутренний Promise.all необходим для полного разрешения Обещания функции sendEmailNotifications только после того, как все .findOne s и analyticsNotification s завершены.

Имейте в виду, что в вашем текущем коде всезапросы отправляются сразу;никакая итерация не зависит от выполнения Обещания последней итерации в первую очередь, если вас это беспокоит.Единственное поведение с блокировкой кода в

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

, где .findOne должен разрешиться до запуска analyticsNotification, но эта логика выглядит необходимой, и обходить ее невозможно.

Я полагаю, что технически возможно превратить ваш код в один огромный массив Обещаний, которые вы называете Promise.all на один раз , путем преобразования каждого элемента user.appId вОбещание и отправка во внешний массив, но это менее функционально, приводит к более уродливому коду и не имеет никакой выгоды, IMO.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...