React中两次连续API调用期间动态添加执行script标签的实现方案
动态脚本加载串联双API调用实现方案
核心实现逻辑
整个流程严格按顺序执行,全程控制加载指示器显隐,核心时序节点如下:
- 流程启动时立即展示加载指示器,所有逻辑执行完成(含异常场景)后再隐藏
- 发起第一次API请求
ApiCall1,解析响应拿到目标脚本地址 - 动态创建带
async属性的script标签插入页面,监听脚本加载、执行完成事件 - 脚本执行完成后取出其返回的业务数据,直接作为payload发起第二次API请求
ApiCall2 - 处理第二次接口返回结果,结束全流程
可直接复用的代码示例
首先准备加载指示器DOM节点:
<div id="loading" style="display: none; position: fixed; inset: 0; background: rgba(255,255,255,0.8); place-items: center;"> 数据加载中... </div>
核心逻辑代码:
const loadingNode = document.getElementById('loading'); // 封装异步脚本加载方法,等待脚本执行完成后返回结果 function loadAsyncScript(url) { return new Promise((resolve, reject) => { const script = document.createElement('script'); script.src = url; script.async = true; // 脚本下载、执行完成后触发onload事件 script.onload = () => { // 需和加载的脚本提前约定结果挂载的全局字段,示例使用__dynamicScriptRet const result = window.__dynamicScriptRet; delete window.__dynamicScriptRet; // 清理全局变量避免命名空间污染 resolve(result); }; script.onerror = () => reject(new Error(`脚本加载失败: ${url}`)); document.head.appendChild(script); }); } async function startBizFlow() { // 流程启动即展示加载态 loadingNode.style.display = 'grid'; try { // 发起第一次API调用 const { url: scriptUrl } = await fetch('/api/endpoint1').then(res => res.json()); // 加载执行脚本,拿到脚本返回的业务数据 const scriptRet = await loadAsyncScript(scriptUrl); // 将脚本返回数据作为payload发起第二次API调用 const finalRes = await fetch('/api/endpoint2', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(scriptRet) }).then(res => res.json()); // 此处编写最终业务逻辑,比如渲染页面、跳转、状态更新等 console.log('全流程执行完成', finalRes); return finalRes; } catch (err) { console.error('流程执行异常', err); // 此处可补充错误提示逻辑 } finally { // 无论成功、失败都关闭加载态 loadingNode.style.display = 'none'; } } // 按业务时机触发流程即可 startBizFlow();
关键注意点
带
async属性的动态脚本不会阻塞页面主线程解析,必须通过onload事件确认脚本执行完成后再取数,否则会出现时序问题导致拿不到脚本返回值。如果加载的脚本没有按约定把结果挂载到示例中的全局字段,对应调整取值逻辑即可,比如部分脚本会把结果挂载到自身专属命名空间下,直接读取对应命名空间的字段即可。
内容的提问来源于stack exchange,提问作者Codingzen
相关产品推荐
相关产品推荐

