JS循环中如何等待forEach内所有异步Promise执行完成后再执行后续代码
完全可以用Promise.all实现,核心是先收集所有toPng返回的Promise实例,再统一等待全部执行完成。
你原代码的问题是forEach是同步遍历方法,执行时只会把所有toPng异步任务推入事件循环,不会等待异步结果返回,所以后续的状态更新代码会立刻执行,和预期逻辑不符。
修改后的代码示例:
// 把handleConvert改为async函数支持await const handleConvert = async () => { const refs = { ...imageRefs.current } // 声明数组收集所有Promise实例 const allPngPromises = [] // 外层循环 Object.keys(refs).forEach(key => { // 内层循环 refs[key].forEach(ref => { // 将toPng返回的Promise存入数组 const pngPromise = toPng(ref) .then((dataUrl) => { props.setImageUrls(old => { return { ...old, // 注意你原代码这里少了一个点,修正为正确的对象展开运算符 [key]: [...old[key], dataUrl] } }) }) .catch(err => { console.error(err) // 这里catch后不抛出错误,保证单个转换失败不会阻塞整体等待逻辑 // 如果需要失败就终止整体流程,可以删掉这里的catch或者在catch中throw err }) allPngPromises.push(pngPromise) }) }) // 等待所有Promise执行完成 await Promise.all(allPngPromises) // 所有异步转换完成后再执行后续代码 if (mounted) { setConverting(false) setConverted(true) } }
补充说明:
- 如果需要严格要求所有
toPng都转换成功才执行后续逻辑,去掉每个promise的单独catch,在外层给Promise.all加try/catch统一捕获错误即可 - 若允许个别图片转换失败仍执行后续状态更新,保留现有每个promise的catch写法即可,catch处理完错误后不抛出异常,
Promise.all会等待所有promise状态敲定后再继续执行后续代码
内容的提问来源于stack exchange,提问作者TheGrumpyDev
相关产品推荐
相关产品推荐

