Tania Rascia

Skip Navigation
Promise.all with Async/Await

Promise.all with Async/Await

 /  8 responses

Let’s say I have an API call that returns all the users from a database and takes some amount of time to complete.

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

Now there’s another call that relies on some information that exists in the entire array of users.

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

And a third call that modifies the second call.

// 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 might try to run the first call, then use a for...of loop to run the subsequent 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:

jon JON andrey ANDREY tania TANIA (3) [{…}, {…}, {…}]

I can use Promise.all() instead to run all of the first, then all the second, then all the third functions.

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)
}
(3) [{…}, {…}, {…}] jon andrey tania JON ANDREY TANIA

Hope that helps someone.

Here’s the whole snippet you can run in the console.

// First promise returns an array 
const getUsers = () => {
  return new Promise((resolve, reject) => {
    return setTimeout(
      () => resolve([
        { id: 'jon' }, 
        { id: 'andrey' }, 
        { id: 'tania' }]),
      600
    )
  })
}

// Second promise relies on the resulting array of first promise
const getIdFromUser = users => {
  return new Promise((resolve, reject) => {
    return setTimeout(() => resolve(users.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()

Newsletter

Get updated when I create new content.
Unsubscribe whenever. Never any spam.

Note

I'm Tania. I turn down every ad, affiliate, and sponsor request I get. I write free resources that help thousands of people successfully become devs. If you enjoy my content, please consider supporting what I do.

Support my work

Write a response

Your email address will not be published. Required fields are marked *

All code will be displayed literally.

Discussion

  • Colby says:

    Is there any reason behind why you chose to return the result of the setTimeout method?

    Really in love with your site, by the way. Would love to build a similar one for my own personal site.

  • Andi says:

    I really like the code theme 🙂

  • Alex says:

    Thank you for sharing.

  • Liciof says:

    good trick, thanks Tania.

  • Kees de Kooter says:

    Shouldn't you use .forEach instead of .map as you are not returning anything?

    • Tania says:

      I'm creating an array of promises with map. forEach wouldn't do that.

    • Mike says:

      She is returning a promise in block "async user => { … }" although you do not see "return" keyword. Async function always return promise automatically and when we do not return own promise then by default returned is resolved promise with undefined value what is this case. This arricle is not very practical because of missing error handling. Also using Promises.all in this case is useless and code was better readable with await. Promise.all is not good alternative to await when we want to run more async functions in series… one by one. Promise.all has real sense when we want to run async functions in parallel. So this example is far away from real world usage and good practice.

      • Mike says:

        Sorry, you run promises for users in parallel. You can mention total time for first and second console output screen. Second example should be 3 times faster for 3 users.