Search code examples
node.jspromiseasync-awaitbluebird

how to run multiple functions respectively while using promises?


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.


Solution

  • 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])