1

I'm trying to run 4 functions in order one by one, I've tried the code below, but some how the function stuck after running the first and the second ones

code exampl:

const Bluebird = require('bluebird');

///// also tried changing all Bluebird below to Promise -> didn't work

//const Promise = require('bluebird');

const promisesFunc = async (array) => {
    let interval = 1000;
    const delayPromise1 = (data, delayDuration) => {
      return new Promise((resolve) => {
        setTimeout(() => {
            /// do some code here requires .map function may take 10s or more
            resolve();
        }, delayDuration)
      });
    };

    const delayPromise2 = (data, delayDuration) => {
      return new Promise((resolve) => {
        setTimeout(() => {
            /// do some code here requires .map function may take 10s or more
            resolve();
        }, delayDuration)
      });
    };

    const delayPromise3 = (data, delayDuration) => {
      return new Promise((resolve) => {
        setTimeout(() => {
            /// do some code here requires .map function may take 10s or more
            resolve();
        }, delayDuration)
      });
    };

    const delayPromise4 = (data, delayDuration) => {
      return new Promise((resolve) => {
        setTimeout(() => {
            /// do some code here requires .map function may take 10s or more
            resolve();
        }, delayDuration)
      });
    };

    try {
    /////////////// first attempt //////////////
    await Bluebird.map(array, (data, index) => delayPromise1(data, index * interval))
    await Bluebird.map(array, (data, index) => delayPromise2(data, index * interval))
    await Bluebird.map(array, (data, index) => delayPromise3(data, index * interval))
    await Bluebird.map(array, (data, index) => delayPromise4(data, index * interval))
    console.log('done ***************************************************');
    setTimeout(() => {
      console.log('response was sent');
      res.status(200).json('done')
    }, 1000);

    /////////////// second attempt ////////////

    const promises = Bluebird.map(array, (data, index) => delayPromise1(data, index * interval))
      .then(() => Bluebird.map(array, (data, index) => delayPromise2(data, index * interval)))
      .then(() => Bluebird.map(array, (data, index) => delayPromise3(data, index * interval)))
      .then(() => Bluebird.map(array, (data, index) => delayPromise4(data, index * interval)))
      .then(() => {
        setTimeout(() => {
          console.log('response was sent');
          res.status(200).json('done')
        }, 1000);
      })
      .catch(err => console.error(err))

      await Promise.all([promises]);

      ///////////// third attempt ////////////////////

      const promises1 = array.map((data, index) => delayPromise1(data, index * interval));
      const promises2 = array.map((data, index) => delayPromise2(data, index * interval));
      const promises3 = array.map((data, index) => delayPromise3(data, index * interval));
      const promises4 = array.map((data, index) => delayPromise4(data, index * interval));
      await Promise.all([promises1, promises2, promises3, promises4]);
      setTimeout(function(){
        console.log('response was sent');
        res.status(200).json('done')
      }, 1000);


    } catch (e) {
      console.error(e);
    }
}
promisesFunc(array)

Note in first and second attempt delayPromise1 and delayPromise2 functions runs successfully but then stops and doesn't continue, other solutions it doesn't work respectively

any idea why this is happening and is there any better solution to promisify these functions to run respectively.

PS functions structure is needed to be like this. and they need to run in order one after the other respectively.

mapping in an array of data , then do some work on it inside delayPromise functions, then resolve(). resolve the promise doesn't have to wait for the code execution to finish in some cases.

3 Answers 3

3

Your third attempt is the way to go. But you could send your response when your Promise.all resolve and all async operations are done.

const promises1 = array.map((data, index) => delayPromise1(data, index * interval));
const promises2 = array.map((data, index) => delayPromise2(data, index * interval));
const promises3 = array.map((data, index) => delayPromise3(data, index * interval));
const promises4 = array.map((data, index) => delayPromise4(data, index * interval));

await Promise.all([promises1, promises2, promises3, promises4]).then(() => {
  console.log('response was sent');
  return res.status(200).json('done')
})
Sign up to request clarification or add additional context in comments.

1 Comment

I've tried this approach, it doesn't wait till the code execution is finished. and it doesn't run them respectively, it runs these functions in parallel.
1

If you want to run parallel pass all delay functions pass inside Promise.all. If you want to run sequentially use like below.

const promisesFunc = async (array) => {
    let interval = 1000;
    const delayPromise1 = (data, delayDuration) => {
        return new Promise((resolve) => {
            setTimeout(() => {
                /// do some code here requires .map function may take 10s or more
                resolve();
            }, delayDuration)
        });
    };

    const delayPromise2 = (data, delayDuration) => {
        return new Promise((resolve) => {
            setTimeout(() => {
                /// do some code here requires .map function may take 10s or more
                resolve();
            }, delayDuration)
        });
    };

    const delayPromise3 = (data, delayDuration) => {
        return new Promise((resolve) => {
            setTimeout(() => {
                /// do some code here requires .map function may take 10s or more
                resolve();
            }, delayDuration)
        });
    };

    const delayPromise4 = (data, delayDuration) => {
        return new Promise((resolve) => {
            setTimeout(() => {
                /// do some code here requires .map function may take 10s or more
                resolve();
            }, delayDuration)
        });
    };

    try {
        console.log("START");
        await Promise.all(array.map((data, index) => delayPromise1(data, index * interval)));
        console.log("Done delayPromise1");
        await Promise.all((array.map((data, index) => delayPromise2(data, index * interval))));
        console.log("Done delayPromise2");
        await Promise.all(array.map((data, index) => delayPromise3(data, index * interval)));
        console.log("Done delayPromise3");
        await Promise.all(array.map((data, index) => delayPromise4(data, index * interval)));
        console.log("Done delayPromise4");
        console.log("DONE");
    } catch (e) {
        console.error(e);
    }
};

promisesFunc([1, 2, 3])

4 Comments

this solution works great, but how to set-timeout for delayPromise function if not resolved , to move on to next one so it doesn't hang
if any promise fails it'll directly go to catch block. ie. if delayPromise1 is done and delayPromise2 does not resolve it'll not execute delayPromise3 and delayPromise4
yes, is there any way to setTimeout on delayPromise2 , 3 and 4 if it didn't resolve , then resolve it , so it move to next function
@sasharomanov if you want to resolve in both the cases, resolve after catch block. It'll always execute.
0

I would use the array .reduce method like so:

[delayPromise1, delayPromise2, ...]
    .reduce((m, delayPromise) => {

        /* here we chain the promises */
        return Promise.resolve(m).then(delayPromise)

    }, {/* any input data to be the argument of delayPromise1 */} )

    .then( res => {

        // do something when all is ready
    })

1 Comment

I don't understand your example, can you explain more using the above code

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.