0

I have several async functions and I want all of them to run synchronously. So tried doing it using promises but it isn't waiting for the third function to complete. It returns to loop after asyncDataRequestOne request.

I searched but I am not able to find examples for chaining promises as below or similar.

Here is what I have tried

Trial 1


function three(j){
 return new Promise((resolve,reject)=>{
   asyncDataRequestThree(()=>{
     let k = j + 14; 
     resolve();
   });
 });
}

function two(i){
 return new Promise((resolve, reject)=>{
  asyncDataRequestOne().then(()=>{
   asyncDataRequestTwo().then(()=>{
     let  = i+ 7;
     three(j);
     resolve()
   });
  });
 });
}

function one(){
  //Each loop should run only after function three's resolve
  arr.forEach((i) => {
    two(i);
  }
}

Trial 2

function async three(j){
   await asyncDataRequestThree(()=>{
     let k = j + 14; 
   });
 });
}

function async two(i){
  await asyncDataRequestOne().then(  async ()=>{
   await asyncDataRequestTwo().then(  async ()=>{
     let  = i+ 7;
     await three(j);
   });
  });
}

function one(){
  //Each loop should run only after function three's resolve
  arr.forEach( async () =>{
    await two(i);
  }
}

Thank you

Ashik Paul
  • 486
  • 4
  • 20
  • 2
    `await one; await two; await three;` Job done :) Avoids Promise hell! Also, `resolve` should be `resolve()`. – Jeremy Thille Jul 03 '20 at 12:01
  • Thanks @JeremyThille. I have tried ```await```. I am not getting the desired results. Could you please show how to link all the three functions. – Ashik Paul Jul 03 '20 at 12:05
  • You have tried await? Sounds promising, can we see this attempt too? – Jeremy Thille Jul 03 '20 at 12:07
  • 1
    Avoid the [`Promise` constructor antipattern](https://stackoverflow.com/q/23803743/1048572?What-is-the-promise-construction-antipattern-and-how-to-avoid-it)! – Bergi Jul 03 '20 at 12:22

2 Answers2

1

Array's forEach loop internally implemented something like this:

for (var element in array) {
  callback(element); // assuming callback is the argument of Array.forEach()
}

So if you add async to function declaration, it will just make it return Promise. Loop will not wait for Promise of the callback to finish, it will wait only for callback itself to finish. Otherwise Array.forEach() would have to return Promise as well.

// assuming asyncDataRequestOne, asyncDataRequestTwo, asyncDataRequestThree will return Promise
async three(j) {
  await asyncDataRequestThree();
  // some kind of operation with j
}

async two(i) {
  await asyncDataRequestOne();
  await asyncDataRequestTwo();
  let j = i + 7;
  await three(j)
}

async function one() {
   for (let i = 0; i < 10; i++) {
      await two(i);
   }
}
Amadare42
  • 415
  • 3
  • 14
  • Thanks @Amadare42. I tried with ```await```. it's not working with all the functions. it's working with one async call only. it doesn't work on multiple. – Ashik Paul Jul 03 '20 at 12:06
  • 2
    You have to provide this async code. Otherwise, it's impossible to tell what is wrong. Provided code will work if `two()` is implemented correctly. – Amadare42 Jul 03 '20 at 12:12
  • Your answer helped me indirectly. Promises don't work with forEach loops. After changing to for loop it worked. Thanks – Ashik Paul Jul 03 '20 at 13:27
0

your two function will be resolved and returns a promise to your loop hence why i will break the chain and it won't await for your three function to resolve which means if you want your three function to return promise before the next loop one of the possibilities is to not use a promise in your two function

function three(p){
  return new Promise((resolve,reject)=>{
     k = p + 14,resolve(console.log(k))
  
 })
}
 function two(i){
  return  j = i+ 7,three(j)
  
 }
 i=0
 function one(){
   //Each loop should run only after function three's resolve
   while(i < 10){
     two(i)
     i++
   }
 }
 one()

or use async await and your code should look something like this

var promise3=function three(p){
  return new Promise((resolve,reject)=>{
     k = p + 14,resolve(console.log(k))
  
 })
}
var promise2=function two(i){
return new Promise((resolve, reject)=>{
  
     let j = i+ 7;
     
     resolve(j)
})
}
 i=0
 async function one(){
   //Each loop should run only after function three's resolve
   while(i < 10){
    r1= await promise2(i)
    r2= await(promise3(r1))

   i++
   }
 }
 one()
Sven.hig
  • 4,449
  • 2
  • 8
  • 18