如何确保多fetch请求执行完成后再返回结果?
问题:多个fetch请求未完成就返回结果
我正在执行多个fetch请求,代码如下:
let var1 = [] let var2 = [] await dateArray?.map((day) => { for (const o of myFirstList) { for (const d of mySecondList) { const resp = fetch(url-with-params) .then((resp) => resp.json()) .then((data) => { const f = manipulateResponse(data) logger.info('1: manipulated data') var1.push(f.data1) var2.push(f.data2) }) } } }) logger.info('2: return response') let response = { var1, var2, } return response
问题在于日志2: return response先被输出,1: manipulated data后输出。我已尝试使用then()和await,请问如何确保所有fetch请求执行完成后,函数再返回完整结果?
解决方案
你的代码存在几个关键问题导致请求未完成就返回:
await作用在dateArray?.map(...)上,但map返回的是普通数组(不是Promise数组),await对普通数组无效,相当于直接跳过等待。- 嵌套循环里的
fetch没有被await,循环会直接往下走,不会等待单个请求完成。 - 所有异步请求没有被统一收集,无法等待全部完成。
修复步骤如下:
1. 收集所有请求的Promise
把每个fetch请求转换成Promise并收集到一个数组里,这样就能用Promise.all等待所有请求完成。
2. 替换map为合适的遍历方式
map是用来转换数组元素的,这里不需要转换,直接用forEach遍历dateArray,同时收集每个循环里的请求Promise。
3. 用Promise.all等待所有请求完成
所有Promise收集完成后,用await Promise.all(promises)等待全部请求处理完毕,再组装返回结果。
修复后的代码示例:
let var1 = [] let var2 = [] // 收集所有请求的Promise const promises = [] dateArray?.forEach((day) => { for (const o of myFirstList) { for (const d of mySecondList) { // 把每个fetch请求的Promise加入数组 const requestPromise = fetch('url-with-params') .then((resp) => resp.json()) .then((data) => { const f = manipulateResponse(data) logger.info('1: manipulated data') var1.push(f.data1) var2.push(f.data2) }) promises.push(requestPromise) } } }) // 等待所有请求完成 await Promise.all(promises) logger.info('2: return response') const response = { var1, var2, } return response
额外优化:避免外部变量(可选)
如果不想用外部的var1和var2,可以让每个Promise返回处理后的数据,最后统一整理:
const promises = [] dateArray?.forEach((day) => { for (const o of myFirstList) { for (const d of mySecondList) { const requestPromise = fetch('url-with-params') .then((resp) => resp.json()) .then((data) => manipulateResponse(data)) promises.push(requestPromise) } } }) // 等待所有请求完成并获取所有处理后的数据 const results = await Promise.all(promises) // 整理结果 const var1 = results.map(res => res.data1) const var2 = results.map(res => res.data2) logger.info('2: return response') return { var1, var2 }
这样代码更清晰,也避免了外部变量的副作用。
内容的提问来源于stack exchange,提问作者albertoivo
相关产品推荐
相关产品推荐

