How to Use Promise.all with Async/Await

Async functions and the await keyword, both introduced in ECMAScript 2017, are more recent innovations to the JavaScript language. These features are essentially syntactic sugar on top of promises, making asynchronous programming easier to write and read. They make async code appear more like synchronous code from the past, thus they’re definitely worth understanding.

To begin, we have the async keyword, which is use to convert a function declaration into an async function. An async function is one that understands how to anticipate the usage of the await keyword to launch asynchronous functionality.

When you combine an async function with the await keyword, the benefit of an async function becomes clear. await only works with async functions in standard JavaScript code, but it can also be use with JavaScript modules on its own. Any async promise-based function can have await in front of it to stop your code on that line until the promise is fulfilled, then return the result. Any function that returns a Promise, including web API calls, can be called using await.

Let’s assume I have an API request that retrieves all of the users from a database and takes a certain length of time.

// First promise returns an array after a delay
const getUsers = () => {
  return new Promise((resolve, reject) => {
    return setTimeout(
      () => resolve([{ id: 'ranjeet' }, { id: 'adil' }, { id: 'preet' }]),
      600
    )
  })
}

Now there’s another request that relies on data that exists throughout the whole user base.

// Second promise relies on the result of first promise
const getIdFromUser = (user) => {
  return new Promise((resolve, reject) => {
    return setTimeout(() => resolve(user.id), 500)
  })
}

There’s also a third call that changes the second.

// Third promise relies on the result of the second promise
const capitalizeIds = (id) => {
  return new Promise((resolve, reject) => {
    return setTimeout(() => resolve(id.toUpperCase()), 200)
  })
}

I’m thinking about doing the first call first, then using a for…of loop to perform the other calls that rely on it.

const runAsyncFunctions = async () => {
  const users = await getUsers()

  for (let user of users) {
    const userId = await getIdFromUser(user)
    console.log(userId)

    const capitalizedId = await capitalizeIds(userId)
    console.log(capitalizedId)
  }

  console.log(users)
}

runAsyncFunctions()

However, this will be my output:

ranjeet

RANJEET
adil
ADIL
preet
PREET
(3) [{…}, {…}, {…}]

Instead, I may call Promise.all() to execute all of the first, second, and third procedures.

const runAsyncFunctions = async () => {
  const users = await getUsers()

  Promise.all(
    users.map(async (user) => {
      const userId = await getIdFromUser(user)
      console.log(userId)

      const capitalizedId = await capitalizeIds(userId)
      console.log(capitalizedId)
    })
  )

  console.log(users)
}

Output:

(3) [{…}, {…}, {…}]
ranjeet
ali
preet

RANJEET
ADIL
PREET

Here is the whole code you can run in the console.

// First promise returns an array after a delay
const getUsers = () => {
  return new Promise((resolve, reject) => {
    return setTimeout(
      () => resolve([{ id: 'ranjeet' }, { id: 'adil' }, { id: 'preet' }]),
      600
    )
  })
}


// Second promise relies on the result of first promise
const getIdFromUser = (user) => {
  return new Promise((resolve, reject) => {
    return setTimeout(() => resolve(user.id), 500)
  })
}


// Third promise relies on the result of the second promise
const capitalizeIds = (id) => {
  return new Promise((resolve, reject) => {
    return setTimeout(() => resolve(id.toUpperCase()), 200)
  })
}

const runAsyncFunctions = async () => {
  const users = await getUsers()

  Promise.all(
    users.map(async (user) => {
      const userId = await getIdFromUser(user)
      console.log(userId)

      const capitalizedId = await capitalizeIds(userId)
      console.log(capitalizedId)
    })
  )

  console.log(users)
}

runAsyncFunctions()

That’s all for this article if you have any queries please contact us through our website or email us at [email protected]. Thank you

Leave a Comment