如何在应用启动及静态变量初始化前完成JSON配置文件的拉取
你使用的fetch为异步API,不会阻塞后续脚本解析执行,因此会出现静态变量初始化完成后请求才返回的时序问题,可通过以下几种方案解决:
方案1:使用同步XMLHttpRequest阻塞后续代码执行
直接在index.html的所有其他JS资源、业务代码引入前执行同步请求,拿到配置后挂载到window全局对象,后续静态变量可直接从全局读取,是最直接满足「静态变量初始化前完成配置拉取」需求的方案。
<script type="text/javascript"> // 必须放在所有<script>标签、静态资源引入的最顶部 const xhr = new XMLHttpRequest(); // 第三个参数设为false代表同步请求,会阻塞后续代码执行 xhr.open('GET', 'config/config.json', false); xhr.send(); if (xhr.status === 200) { // 配置挂载到全局,所有后续代码可直接访问 window.GLOBAL_CONFIG = JSON.parse(xhr.responseText); } else { throw new Error('全局配置加载失败,请检查config.json路径是否正确'); } </script> <!-- 后面再放置项目的其他脚本引入、业务代码 -->
注意:同步请求仅会在配置加载期间短暂阻塞渲染,配置文件体积不大的情况下对用户体验几乎无影响。
方案2:将配置改为JS文件提前引入
不需要发起网络请求,直接把JSON配置转为JS变量挂载到全局,在index.html中最先引入该配置文件,完全不会出现时序问题,性能最优。
config/config.js内容:
window.GLOBAL_CONFIG = { // 填入原JSON配置内容即可 env: "prod", apiBaseUrl: "https://xxx.xxx.com" }
index.html引入:
<!-- 放在所有其他脚本的最前面 --> <script src="config/config.js"></script>
后续静态变量直接读取window.GLOBAL_CONFIG即可。
方案3:延迟应用初始化时机
如果不想使用同步请求,可调整应用启动逻辑,所有静态变量初始化、应用挂载都放到异步请求的回调中执行,适合React/Vue等框架类项目。
以React项目为例,调整入口文件逻辑:
import React from 'react'; import ReactDOM from 'react-dom/client'; import App from './App'; // 先拉取配置,再初始化应用 fetch('config/config.json') .then(res => res.json()) .then(data => { window.GLOBAL_CONFIG = data; // 拿到配置后再执行应用挂载、静态变量初始化 const root = ReactDOM.createRoot(document.getElementById('root')); root.render(<App />); }) .catch(e => console.error('配置加载失败', e))
Vue项目同理,将createApp(App).mount('#app')逻辑放到fetch回调中执行即可。
内容的提问来源于stack exchange,提问作者Đoàn Trí
相关产品推荐
相关产品推荐

