如何在JavaScript回调函数外部使用JSON数据并赋值给变量
问题本质
你无法在回调函数外部拿到数据,核心原因是**fetch和async逻辑都是异步非阻塞的**:JS执行到load()调用时不会等待请求返回,会直接往下跑后续同步代码,这时候请求还没完成,你在外层读变量自然只能拿到undefined,本质是执行时序问题,不是作用域问题。不要尝试把异步请求改成同步阻塞模式,会导致页面卡死,顺着异步逻辑处理即可实现全局访问。
实现方案
方案1:全局缓存Promise实例(推荐)
只需要发起一次请求,任意位置需要用数据时直接await取值即可,不会重复请求,也不用提前等待加载完成:
// 全局作用域声明,页面加载时只发起一次JSON请求 const sorularDataPromise = load(); async function load() { const url = 'sorular.json'; return (await fetch(url)).json(); } // 任意业务函数中需要用到数据时,按如下方式调用即可 async function handleBusiness() { // 首次调用会等待请求完成,后续调用会直接返回已缓存的JSON数据 const sorularData = await sorularDataPromise; // 后续直接操作sorularData即可 console.log(sorularData); }
方案2:初始化阶段完成全局变量挂载
如果你的业务逻辑必须等JSON加载完成才能启动,可以在应用入口处先完成数据赋值,再执行后续逻辑:
// 声明全局变量 let sorularGlobalData = null; async function load() { const url = 'sorular.json'; return (await fetch(url)).json(); } // 应用入口函数 async function appInit() { // 等待数据加载完成后挂载到全局 sorularGlobalData = await load(); // 数据挂载完成后,再启动所有依赖这份数据的业务逻辑 // 例如 renderPage()、bindEvent() 等操作全部放在这之后执行 console.log('全局JSON数据加载完成', sorularGlobalData); } // 启动应用 appInit();
避坑提醒
- 不要尝试在异步回调外的同步代码中直接读取全局变量,例如下面的写法永远拿不到正确值:
let testData = null; load().then(res => { testData = res; }) console.log(testData) // 执行到这行时请求还没返回,永远输出null
- 所有依赖这份JSON数据的逻辑,要么放在
await请求完成之后执行,要么通过缓存Promise的方式按需等待取值。
内容的提问来源于stack exchange,提问作者Eren Talan
相关产品推荐
相关产品推荐

