JavaScript中fetch获取数据完成后如何正确执行后续代码
问题原因
你遇到的问题本质是fetch属于异步Web API,JS执行到fetch语句时只会把请求丢给浏览器线程处理,自身不会阻塞等待结果返回,会立刻往下执行后续同步代码,所以外层的console.log(array)会在请求还没返回、array还没被赋值的时候执行,自然打印undefined。
靠setTimeout写固定延迟的做法完全不可靠:网络波动、文件体积变化都可能导致请求耗时超过你设置的延迟,出现偶发拿不到数据的bug,延迟设太长又会浪费等待时间。
正确实现方式
所有需要操作加载后数组的逻辑,必须等fetch请求完成、数据赋值成功后再执行,有两种常用写法:
1. 直接在Promise的then链中处理数据
这是兼容性最好的基础写法,不需要考虑运行环境支持:
// 声明全局数组 let productArray; fetch("products.json") .then(res => { // 先判断请求是否成功,fetch只有网络错误才会reject,HTTP 4xx/5xx不会抛错 if (!res.ok) throw new Error("请求失败,状态码:" + res.status); return res.json(); }) .then(data => { // 到这里数据已经加载完成,给全局数组赋值 productArray = data; // 所有依赖productArray的逻辑直接写在这里,会在数据就绪后自动执行 console.log("加载完成的产品数组:", productArray); // 比如渲染列表、做数据筛选等操作都放这 }) .catch(err => { // 一定要加错误捕获,处理请求失败、JSON解析出错的场景 console.error("产品数据加载失败:", err); }) // 注意:不要在这个同步位置直接访问productArray,这里执行时数据还没加载完
2. 使用async/await语法写异步逻辑
这种写法代码结构更接近同步逻辑,可读性更好,现代浏览器、Node.js 14.8以上版本还支持直接在顶层使用await:
let productArray; // 顶层await写法,支持的环境可以直接用 try { const res = await fetch("products.json"); if (!res.ok) throw new Error("请求失败,状态码:" + res.status); productArray = await res.json(); // await之后的代码都是数据加载完成后才执行,直接操作数组即可 console.log("加载完成的产品数组:", productArray); } catch (err) { console.error("产品数据加载失败:", err); }
如果需要兼容不支持顶层await的环境,可以把逻辑包在立即执行的async函数里:
let productArray; // 立即执行的异步函数 (async function initApp() { try { const res = await fetch("products.json"); if (!res.ok) throw new Error("请求失败,状态码:" + res.status); productArray = await res.json(); // 数据就绪后的逻辑全写在这里 console.log("加载完成的产品数组:", productArray); } catch (err) { console.error("产品数据加载失败:", err); } })()
注意事项
- 绝对不要依赖固定延迟等待异步请求结果,这种写法没有任何可靠性可言
- 所有依赖异步加载数据的逻辑,必须放在请求完成的回调节点内(then回调里、await语句之后)
- fetch默认只有网络层面的错误会触发catch,HTTP 404、500这类错误需要自己通过
res.ok判断处理
内容的提问来源于stack exchange,提问作者NVSS
相关产品推荐
相关产品推荐

