繁体   English   中英

Promise.all或嵌套异步等待哪个更好?

[英]Which is better Promise.all or nested async await?

我有两个代码块。 首先是使用async await

  async sendEmailNotifications() {
    try {
      const users = await User.find(...)

      const promises = users.map(async(user) => {
        const _promises = user.appId.map(async(app) => {
            const todayVisitorsCount = await Session.count({...})
            const yesterdayVisitorsCount = await UserSession.count({...})
            const emailObj = {
              todayVisitorsCount,
              yesterdayVisitorsCount
            }
            const sendNotification = await emailService.analyticsNotification(emailObj)
        })
        await Promise.all(_promises)
      })
      return promises
    } catch (err) {
      return err
    }
  }
(await sendEmailNotifications())

然后我使用了Promise.all

    sendEmailNotifications() {
      const users = await User.find(...)
      const promises = users.map((user) => {
        const allPromises = []
        user.appId.map((app) => {
          allPromises.push(UserSession.count({...}))
          allPromises.push(Session.count({...}))
        })
        const data = await Promise.all(allPromises)
        const emailObj = {
          todayVisitorsCount: data[0],
          yesterdayVisitorsCount: data[1]
        }
        const sendNotification = await emailService.analyticsNotification(emailObj)
      })
      return promises
  }


  sendNotification.then((data) => console.log(data))

现在我需要知道哪段代码可以更快地执行? 一种是使用series(异步等待),另一种是使用parellel(Promise.all)。 哪个有更好的表现?

在第一个代码中,您有两个单独的await语句:

        const todayVisitorsCount = await Session.count({...})
        const yesterdayVisitorsCount = await UserSession.count({...})

而在第二个中, Promise.all之前只有一个。

const data = await Promise.all(allPromises)

在第一个代码中,第二个Promise仅在第一个Promise完成后才初始化,从而导致脚本结束之前需要更长的时间。 例如:

 const fn = () => new Promise(resolve => setTimeout(resolve, 1000)); console.log('start'); (async () => { await fn(); await fn(); console.log('two awaits done'); })(); (async () => { await Promise.all([fn(), fn()]); console.log('Promise.all done'); })(); 

没有Promise.all的版本会在第一次调用fn()时暂停该函数,并等待fn()返回的Promise解析(1000 ms),然后继续进行下一行。 下一行再次调用fn() ,并且await等待它完成(另外1000毫秒)。

相比之下, Promise.all版本同时呼吁fn() š立即-无论是承诺的初始化,并且await ,即暂停该功能正在等待双方的承诺来完成。 在第一个Promise的初始化和第二个Promise的初始化之间没有停机时间。

因此, Promise.all版本将比带有两个await的版本运行得更快。 最好使用Promise.all 除非 必须在第二个Promise( Session.count )开始之前完成第一个Promise( UserSession.count )。

通过解构和没有不必要的变量,这就是我清理Promise.all代码的方式,您可能会认为它更具可读性:

async sendEmailNotifications() {
  const users = await User.find();
  return users.map(async (user) => {
    const [todayVisitorsCount, yesterdayVisitorsCount] = await Promise.all([
      UserSession.count(),
      Session.count()
    ]);
    await emailService.analyticsNotification({ todayVisitorsCount, yesterdayVisitorsCount });
  });
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM