skip to Main Content

after reviewing a number of questions around for/foreach loops I am still not able to get an output of a promise.all batch of functions.

The goal is to call each iteration of doSleepNow() synchronously, but wait in the Promise.all until all results are in before continuing with a .then()

in the below simplified code extract output_A should be giving four versions of doSleepNow().myTimeRes, however I get

myFun1 msg:  All array for myFun1 done
promToCall outputs (myTimeRes) :  [
  [ [Function: promToCall] ],
  [ [Function: promToCall] ],
  [ [Function: promToCall] ],
  [ [Function: promToCall] ]
]

what am I missing to have the Promise.all trigger each loop of doSleepNow()

*Note: using sleep fn as functional stub only

const myArr = [
  {"hello":"Bob"},
  {"hello":"Jane"},
  {"hello":"Elvis"},
  {"hello":"Zac"}
]
var myOutPromArr = [];
    
const sleep = (waitTimeInMs) => new Promise(resolve => setTimeout(resolve, waitTimeInMs));
    
async function doSleepNow(waittime, loopnum) {
    return new Promise((resolve, reject) => {
        var now = new Date().toISOString();
        const inTime = "Time Start sleep for " + loopnum + " is : " + now;
        sleep(waittime).then(() => {
            const now = new Date().toISOString();
            const outTime = "Time End sleep for " + loopnum + " is : " + now;
            const myTimeRes = "myTime = " + inTime + " : " + outTime
            console.log("w" + inTime + " : " + outTime)
            resolve(myTimeRes)
        });
    })
}

async function myFun1(waittime) {
    return new Promise((resolve, reject) => {
        const myArrLen = myArr.length
        var arrCount = 0;
        myArr.forEach((value) => {
            arrCount++
            const promToCall = (waittime, arrCount) => new Promise(resolve => doSleepNow(waittime, arrCount))
            myOutPromArr.push([promToCall])
            if (myArrLen === arrCount) {
                resolve("All array for myFun1 done")
            }
        })
    })
}

myFun1(1000).then((status) => {
    console.log("myFun1 msg: ", status)
    sleep(5000).then(() => {
        Promise.all(myOutPromArr).then((values) => {
            console.log("promToCall outputs (myTimeRes) : ", values); // <== output_A
        })
    })
})

2

Answers


  1. You can use Promise.all and you are creating an array of arrays. If you pass that to promise.all it’ll not work.

    const myArr = [
      { hello: "Bob" },
      { hello: "Jane" },
      { hello: "Elvis" },
      { hello: "Zac" },
    ];
    
    const sleep = (waitTimeInMs) =>
      new Promise((resolve) => setTimeout(resolve, waitTimeInMs));
    
    function doSleepNow(waittime, loopnum) {
      var now = new Date().toISOString();
      const inTime = "Time Start sleep for " + loopnum + " is : " + now;
      return sleep(waittime).then(() => {
        const now = new Date().toISOString();
        const outTime = "Time End sleep for " + loopnum + " is : " + now;
        const myTimeRes = "myTime = " + inTime + " : " + outTime;
        return myTimeRes;
      });
    }
    
    function myFun1(waittime) {
      return myArr.map((_, i) => doSleepNow(waittime, i));
    }
    
    const list = myFun1(1000);
    console.log("myFun1 msg: ");
    sleep(500).then(() => Promise.all(list)).then((values) => {
        console.log("promToCall outputs (myTimeRes) : ", values);
      });
    Login or Signup to reply.
  2. Your main issue is that your myOutPromArr function is an array of arrays of functions. What you want is an array of promises.

    Here is a modified version of your code (trying to keep it as similar as possible to the original) which is more correct. I also took the time to simplify some code to use async/await.

    const myArr = [
      {"hello":"Bob"},
      {"hello":"Jane"},
      {"hello":"Elvis"},
      {"hello":"Zac"}
    ]
    
        
    const sleep = (waitTimeInMs) => new Promise(resolve => setTimeout(resolve, waitTimeInMs));
        
    async function doSleepNow(waittime, loopnum) {
      let now = new Date().toISOString();
      const inTime = "Time Start sleep for " + loopnum + " is : " + now;
      await sleep(waittime)
      
      now = new Date().toISOString();
      const outTime = "Time End sleep for " + loopnum + " is : " + now;
      const myTimeRes = "myTime = " + inTime + " : " + outTime
      return myTimeRes;
    }
    
    async function myFun1(waittime) {
      const myArrLen = myArr.length
      var myOutPromArr = [];
      
      myArr.forEach((value, index) => {
        const promise = doSleepNow(waittime, index + 1)
        myOutPromArr.push(promise)
      })
      
      return myOutPromArr;
    }
    
    myFun1(1000).then((promises) => {
        sleep(5000).then(() => {
            Promise.all(promises).then((values) => {
                console.log("promToCall outputs (myTimeRes) : ", values); // <== output_A
            })
        })
    })
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search