如何监听forEach循环中所有Fetch请求的完成事件?
问题描述
我当前的代码如下:
window.addEventListener('load', fetchInfo) function fetchInfo() { const tableRows = //an array of results tableRows.forEach((row) => { const rowId = //get the id of each row fetch(...) //fetch some stuff using the id .then(() => { //do some stuff return rowId; }) .then((id) => { //do some stuff }) }) }
我通过rowId获取信息并填充表格行,最多会发起10次Fetch请求(表格最多10行)。我需要监听所有请求完成的事件,即表格完全加载完成的时机,该如何实现?
补充说明:这些Fetch是API请求,响应需要几秒时间。我曾尝试使用Promise.all(tableRows.map(row) =>,但它在API响应前就返回了结果,无法准确检测表格何时加载完成。
解决方案
你之前用Promise.all时提前返回,核心问题是没在map回调里返回完整的Promise链,导致Promise.all拿到的是一堆undefined,自然会立刻“完成”。
正确实现方式
用map替代forEach,让每个迭代项返回整个fetch的Promise链,再用Promise.all包裹,就能监听所有请求+后续处理全部完成的时机:
方式1:async/await写法
window.addEventListener('load', fetchInfo) async function fetchInfo() { const tableRows = //an array of results // 生成包含所有请求Promise的数组 const rowPromises = tableRows.map((row) => { const rowId = //get the id of each row // 必须return整个Promise链 return fetch(...) .then(() => { //do some stuff return rowId; }) .then((id) => { //do some stuff }) }) // 等待所有请求和后续处理完成 await Promise.all(rowPromises) // 这里就是表格完全加载完成的时机 console.log('所有行已加载完毕') // 可在此处执行加载完成后的逻辑:隐藏加载动画、更新页面状态等 }
方式2:Promise链式写法
如果不想用async/await,也可以用传统的.then链式调用:
window.addEventListener('load', fetchInfo) function fetchInfo() { const tableRows = //an array of results const rowPromises = tableRows.map((row) => { const rowId = //get the id of each row return fetch(...) .then(() => { //do some stuff return rowId; }) .then((id) => { //do some stuff }) }) Promise.all(rowPromises) .then(() => { console.log('所有行已加载完毕') // 加载完成后的逻辑写在这里 }) .catch((err) => { // 处理任意一个请求失败的情况 console.error('有请求加载失败:', err) }) }
额外场景:忽略个别请求失败
如果希望不管个别请求成功还是失败,都等所有请求完成再执行后续逻辑,可以用Promise.allSettled替代Promise.all:
Promise.allSettled(rowPromises) .then((results) => { console.log('所有请求已处理完成(无论成功失败)') // 可遍历results查看每个请求的状态 results.forEach((result, index) => { if (result.status === 'fulfilled') { console.log(`第${index+1}行加载成功`) } else { console.error(`第${index+1}行加载失败`, result.reason) } }) })
内容的提问来源于stack exchange,提问作者maybemonday
相关产品推荐
相关产品推荐

