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
})
})
})
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
})
})
})