Raffy
Raffy

Reputation: 35

Return dependent promises sequentially inside loop

I'm working on shopify integration. We receive an array items then loop through them and add them a new model (func1) then I need to use that result from the first and add it to a schedule (func2).

I need this functions to run sequentially because I'm adding the results to a schedule and if I have two results for the same date and they don't yet exist in the database if the they run in parallel it creates 2 separate entries in the database instead of one entry with the two values.

The way I need to return is func1, func2, func1, func2....

But at the moment is returning func1, func1...func2, func2...

This is a simplified example of what I need to accomplish.

 const func2 = () => {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          return console.log('func2');
        }, 3000);
      });
    };

const func1 = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log('Func1');
      func2();
    }, 1000);
  });
};

const array = [1, 2, 3, 4, 5];

const test = () => {
  array.map(x => {
    func1();
  });
};
test();

If there is something that isn't clear please let me know. Thanks

Upvotes: 1

Views: 45

Answers (3)

Mohammed Ashfaq
Mohammed Ashfaq

Reputation: 3426

const func2 = async (modalValue) => {
  let result = modalValue*5;
  console.log(`Function2 result: ${result}`)
  return result; 
};


async function getModalValue(i){
  // rest of your Code
  return { modal: i*2}
}


const func1 =  async (item) => { 
   let {modal} = await getModalValue(item);
   console.log(`Function1 modal: ${modal}`)
   await func2(modal);
};

const array = [1, 2, 3, 4, 5];

const test = async () => {
  for(let i=0;i<array.length;i++){
    await func1(array[i]);
  }
};

test().then((resp)=> {console.log("Completed")})
 .catch((err)=>{console.log("failure")})

Upvotes: 0

Aadit M Shah
Aadit M Shah

Reputation: 74204

This is the perfect place to use the traverse function:

const traverse = (xs, f) => xs.reduce((promise, x) =>
    promise.then(ys => f(x).then(y => Promise.resolve(ys.concat([y])))),
    Promise.resolve([]));

const times2 = x => new Promise(resolve => setTimeout(() => {
    console.log("times2", x);
    resolve(2 * x);
}, 1000));

const minus1 = x => new Promise(resolve => setTimeout(() => {
    console.log("minus1", x);
    resolve(x - 1);
}, 1000));

const xs = [1,2,3,4,5];

const ys = traverse(xs, x => times2(x).then(minus1));

ys.then(console.log); // [1,3,5,7,9]

Hope that helps.

Upvotes: 0

Amit Wagner
Amit Wagner

Reputation: 3264

you can use async/await and for loop in order do create a synced like iteration. and use it again in your func1 in order to reslove

const func2 = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
       console.log('func2');
       resolve();
    }, 3000);
  });
};

const func1 =  () => {
  return new Promise( (resolve, reject) => {
  setTimeout(async () => {
      console.log('Func1');
      await func2();
      resolve();
    }, 1000);
  });
};

const array = [1, 2, 3, 4, 5];

const test = async () => {
  for(let i=0;i<array.length;i++){
    await func1();

  }
};
test();

Upvotes: 1

Related Questions