JavaScript中如何结合forEach循环正确使用Promise.all?
问题分析与解决方案
核心问题
你当前的myOutPromArr里存的是未执行的函数(还套了一层数组),而Promise.all需要接收已执行的Promise实例数组。这些函数根本没被调用,所以doSleepNow完全没触发,自然拿不到预期结果。
关键修正步骤
- 直接生成Promise实例存入数组:
删掉promToCall这个多余的函数包装,直接调用doSleepNow(waittime, arrCount),把它返回的Promise直接push进数组,不要额外包一层数组。 - 简化冗余的Promise嵌套:
doSleepNow本身是async函数,无需手动new Promise,直接用await替代.then让代码更简洁;myFun1作为async函数,不用手动构建Promise,直接用map遍历数组生成Promise数组即可。
- 修正调用逻辑:
不需要额外的sleep(5000),myFun1直接返回所有Promise的数组,后续用Promise.all等待全部完成。
修正后的完整代码
const myArr = [ {"hello":"Bob"}, {"hello":"Jane"}, {"hello":"Elvis"}, {"hello":"Zac"} ] const sleep = (waitTimeInMs) => new Promise(resolve => setTimeout(resolve, waitTimeInMs)); // 简化doSleepNow:async函数自动返回Promise,无需手动包装 async function doSleepNow(waittime, loopnum) { const nowStart = new Date().toISOString(); const inTime = `Time Start sleep for ${loopnum} is : ${nowStart}`; await sleep(waittime); const nowEnd = new Date().toISOString(); const outTime = `Time End sleep for ${loopnum} is : ${nowEnd}`; const myTimeRes = `myTime = ${inTime} : ${outTime}`; console.log(`w${inTime} : ${outTime}`); return myTimeRes; } // 简化myFun1:直接生成Promise数组返回 async function myFun1(waittime) { return myArr.map((_, index) => { // 用index+1作为loopnum,保证从1开始计数 return doSleepNow(waittime, index + 1); }); } // 修正调用逻辑:用Promise.all等待所有Promise完成 myFun1(1000).then((promiseArr) => { console.log("myFun1 msg: All array for myFun1 done"); Promise.all(promiseArr).then((values) => { console.log("promToCall outputs (myTimeRes) : ", values); }); });
补充说明
如果你的「同步调用」是指顺序执行(上一个doSleepNow完成后再执行下一个),而非并行触发,那么需要改成循环await的方式:
async function myFun1Sequential(waittime) { const results = []; for (let i = 0; i < myArr.length; i++) { const result = await doSleepNow(waittime, i + 1); results.push(result); } return results; } // 调用时直接拿到顺序执行的结果 myFun1Sequential(1000).then((values) => { console.log("sequential outputs: ", values); });
内容的提问来源于stack exchange,提问作者art vanderlay
相关产品推荐
相关产品推荐

