如何只加载一次JSON文件并在函数外使用其全部内容
问题原因
该现象是由fetchAPI的异步执行特性导致的:
JS引擎执行代码时会优先跑完所有同步代码,再处理异步回调的返回结果。全局位置的
console.log(jsonCompleto)属于同步代码,执行时fetch请求还未完成,jsonCompleto还未被赋值,因此返回undefined。
解决方案
方案1:使用顶层await(推荐,现代JS环境支持)
直接在全局作用域用await等待fetch返回结果,赋值后再执行后续逻辑,确保用到jsonCompleto时数据已经加载完成:
// 全局只发起一次请求 const jsonCompleto = await fetch('uno.json') .then(response => response.json()) // 之后全局任意位置都可以直接使用 console.log(jsonCompleto)
如果运行环境不支持顶层await,可把所有依赖该JSON数据的逻辑封装到同一个async函数里执行:
let jsonCompleto async function init() { const data = await fetch('uno.json').then(res => res.json()) jsonCompleto = data // 所有需要用到jsonCompleto的逻辑都在init内部调用,或者等init执行完成后再调用 runYourBusinessCode() } init()
方案2:在回调函数中触发后续逻辑
如果不想用async/await,也可以把依赖JSON数据的逻辑封装成独立函数,在fetch的.then回调中调用,保证执行时数据已经存在:
let jsonCompleto fetch('uno.json') .then(response => response.json()) .then(data => { jsonCompleto = data // 调用需要用到JSON数据的业务函数 runYourBusinessCode() }) function runYourBusinessCode() { // 这里可以正常拿到完整的jsonCompleto console.log(jsonCompleto) }
全局只加载一次的实现
如果要避免重复发起请求,可以加一层缓存判断,后续再调用的时候直接返回已经加载好的数据:
let cachedJson = null async function getJsonCompleto() { if (cachedJson) return cachedJson cachedJson = await fetch('uno.json').then(res => res.json()) return cachedJson } // 任意位置调用,只会发起一次请求 const data1 = await getJsonCompleto() const data2 = await getJsonCompleto() // 直接返回缓存,不会发新请求
内容的提问来源于stack exchange,提问作者mirta
相关产品推荐
相关产品推荐

