Vanilla.js多次调用Fetch API存结果到数组时得到空数组问题
问题根因
Array.prototype.forEach 本身不支持等待异步回调执行,你传入的async回调会被同步触发,内部的await fetch不会阻塞forEach的遍历流程,遍历结束后代码会立刻执行console.log(responseData),此时所有接口请求还处于pending状态,没有任何数据被push进数组,所以打印结果为空。
正确实现
推荐使用Promise.all配合map并行发起所有请求,等待所有接口返回后再统一处理数据,性能更高:
const regions = [123, 12312, 1231231, 123123, 123123]; const getResponse = async () => { // 遍历生成所有请求的Promise任务 const requestTasks = regions.map(async (code) => { // 修正原代码接口地址缺少//的笔误 const response = await fetch(`https://service.org?where=id=${code}`); const data = await response.json(); return data.features[0]; }); // 等待所有请求完成,拿到按原数组顺序排列的结果 const responseData = await Promise.all(requestTasks); console.log(responseData); // 浏览器环境生成并下载JSON文件 const jsonContent = JSON.stringify(responseData, null, 2); const blob = new Blob([jsonContent], { type: "application/json" }); const downloadLink = document.createElement("a"); downloadLink.href = URL.createObjectURL(blob); downloadLink.download = "region-data.json"; downloadLink.click(); URL.revokeObjectURL(downloadLink.href); }; getResponse();
可选方案
如果接口有并发限制,不适合同时发起大量请求,可以用for...of循环串行发起请求,保证同一时间只有一个请求在执行:
const getResponseSerial = async () => { const responseData = []; for (const code of regions) { const response = await fetch(`https://service.org?where=id=${code}`); const data = await response.json(); responseData.push(data.features[0]); } console.log(responseData); // 后续生成JSON逻辑和上面一致 };
注意:不要尝试给
forEach本身加异步等待逻辑,forEach的设计就是同步遍历,没有返回值,不支持异步等待场景。
内容的提问来源于stack exchange,提问作者Sulove Dahal
相关产品推荐
相关产品推荐

