Home > Software engineering >  How to async await in promise.all
How to async await in promise.all

Time:10-16

i wnna make an API thing that load list of pokemons and when it's image. got the list and wanna make sure the sequence on pictures will be correct for this i console.log the same names. and sequence is wrong. tried some async await in diff places and can't figure out how to get proper order https://codepen.io/DeanWinchester88/pen/ExvxdxX

Promise.all(arrForFetch)
    .then(files => {
        files.forEach(file => {
            console.log("files", file)
            process(file.json())
        })
            .catch(err => console.log("tobie pizda ucziekaj"))
    })
let process = (prom) => {
    console.log(prom)
    prom.then(data => {
        console.log(data.name)
    })
}

CodePudding user response:

const results = await Promise.all(arrForFetch)
// do something with results array

Your issue is that file.json() is async so needs to be returned from the loop as another Promise all, or awaited in the loop. You can map the promises.

(async function(){

await Promise.all(arrForFetch)
                 .then( files  =>{
                     const more = files.map(file=>file.json().then(process))
                     return Promise.all(more)
                   })
                  .catch(err  =>  console.log("tobie pizda ucziekaj"))

})();
(async function(){

await Promise.all(arrForFetch)
                 .then( async files  =>{
                     for(const i=0; i<files.length; i  ){
                     console.log("files", files[i])
                     process(  await files[i].json() )
                     }
                   })
                  .catch(err  =>  console.log("tobie pizda ucziekaj"))

})();

CodePudding user response:

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 = (user) => {
  return new Promise((resolve, reject) => {
    return setTimeout(() => resolve(user.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)
}

Output:

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