Vue3中如何等待外部Google Pay脚本加载就绪?
替代setTimeout等待Google Pay脚本加载的更好方案
直接用固定时长的setTimeout确实不靠谱——网络环境波动会导致要么提前执行时脚本还没就绪,要么白白浪费等待时间。下面是几种更可靠的方案:
方法1:利用脚本的onload事件触发初始化
这是最直接的方式,脚本加载完成后会立即触发onload回调,完全不需要猜等待时间:
onMounted(()=>{ const scriptUrl = "https://pay.google.com/gp/p/js/pay.js"; const tag = document.createElement("script"); tag.src = scriptUrl; tag.async = true; // 脚本加载完成后立即初始化Google Pay tag.onload = () => { if ('google' in window) { loadGooglePay(); } }; // 额外处理脚本加载失败的情况 tag.onerror = () => { console.error("Google Pay脚本加载失败"); // 这里可以加用户提示或降级逻辑 }; document.head.appendChild(tag); });
方法2:用MutationObserver监听window属性变化
如果遇到脚本加载完成后,window.google不会立即挂载的极端情况,可以用观察者监听window对象的属性变化,确保目标对象就绪后再执行:
onMounted(()=>{ const scriptUrl = "https://pay.google.com/gp/p/js/pay.js"; const tag = document.createElement("script"); tag.src = scriptUrl; tag.async = true; document.head.appendChild(tag); // 创建观察者监听window属性变化 const observer = new MutationObserver((mutations) => { if ('google' in window) { loadGooglePay(); observer.disconnect(); // 完成后停止监听,避免资源浪费 } }); observer.observe(window, { attributes: true, subtree: false }); // 加个超时兜底,防止观察者一直挂着 setTimeout(() => { observer.disconnect(); console.warn("Google Pay脚本加载超时"); }, 5000); });
方法3:用Promise封装脚本加载逻辑
如果项目习惯用异步/await风格,可以把脚本加载封装成Promise,代码更整洁:
function loadScript(url) { return new Promise((resolve, reject) => { const tag = document.createElement("script"); tag.src = url; tag.async = true; tag.onload = () => resolve(); tag.onerror = () => reject(new Error(`加载脚本失败: ${url}`)); document.head.appendChild(tag); }); } onMounted(async ()=>{ try { await loadScript("https://pay.google.com/gp/p/js/pay.js"); if ('google' in window) { loadGooglePay(); } } catch (err) { console.error(err); } });
这些方案的优势:
- 完全贴合脚本实际加载完成的时机,不会出现提前或延迟执行的问题
- 支持异常处理,能应对脚本加载失败的场景
- 代码逻辑更清晰,可维护性更强
内容的提问来源于stack exchange,提问作者volume one
相关产品推荐
相关产品推荐

