1

I'm trying to create a "synchronized like loop" with async await but I get the strange behavior of getting all the results after the first promise instead.

here is my test case. See how you get all together instead of print 1 by 1

const p = () =>  new Promise((resolve) =>{
   setTimeout(()=>{
       resolve(Math.floor(Date.now() / 1000))
   },1000)

})

const test =  () =>{

 [1,2,3,4,5,6,7,8,9,10].map(async () =>{
      const e = await p();
      console.log(e)
  });
  
}

test();
fool-dev
  • 7,671
  • 9
  • 40
  • 54
Amit Wagner
  • 3,134
  • 3
  • 19
  • 35
  • map doesn't work with `aync / await` But if you used say bluebird promise, it does have a promise based map. Alternatively in your example a for-loop would work. – Keith Jan 08 '18 at 11:49

1 Answers1

3

Like I mention in comments, map is not Promise aware. There are alternatives like Bluebirds.map,.. But the easy option is to use a for loop,..

Keeping to your example were your wanting to loop an array, you can use the for of variant too. Changing to for (let a = 1; a <= 10; a ++) will work too.

eg.

const p = () =>  new Promise((resolve) =>{
   setTimeout(()=>{
       resolve(Math.floor(Date.now() / 1000))
   },1000)

})

const test =  async () =>{
 for (const a of [1,2,3,4,5,6,7,8,9,10]) {
   const e = await p();
   console.log(e)
 }  
}

test();

It's also worth pointing out bluebirds map has another trick up it's sleeve, it has a concurrency option. This is very handy to prevent thrashing that can happen with Promise.all, you basically say you want to do x promises at a time, eg. you have 10 promises to do, but you find it's more optimal to do 3 concurrently.

Keith
  • 22,005
  • 2
  • 27
  • 44