Chrome扩展中setTimeout注入jQuery及依赖加载异常问题排查
问题解答
你的猜测完全正确——由于两个脚本是并行发起加载请求的,网络环境波动、资源文件大小差异等因素,都可能导致myLibrary比jQuery更早加载完成,此时onMyLibraryLoaded里调用$自然会抛出“jQuery未定义”的错误。
下面提供几种可靠的解决方案,也会说明如何用await来解决这个问题:
方案1:强制按顺序加载(最稳妥)
确保jQuery完全加载完成后,再去加载myLibrary,从根源上避免依赖顺序问题。可以把加载逻辑包装成Promise,用async/await控制顺序:
// 确保jQuery就绪的Promise函数 function ensurejQuery() { return new Promise(resolve => { if (window.jQuery) { resolve(); return; } const script = document.createElement('script'); script.src = 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js'; script.onload = () => { console.log('jquery loaded successfully'); resolve(); }; document.body.appendChild(script); }); } // 加载myLibrary的Promise函数 function loadMyLibrary() { return new Promise(resolve => { if (window.myLibrary) { resolve(); return; } const script = document.createElement('script'); script.src = 'https://jrags/myLibrary.min.js'; script.onload = resolve; document.body.appendChild(script); }); } // 按顺序初始化脚本 async function init() { await ensurejQuery(); await loadMyLibrary(); // 此时jQuery和myLibrary都已就绪,安全绑定事件 $(document).on("blur", "#someInput", function(){ console.log("Input blurred"); }); } init();
方案2:在myLibrary回调中等待jQuery就绪
如果不想调整加载顺序,可以在onMyLibraryLoaded里轮询检查jQuery是否存在,直到可用再执行绑定逻辑:
function onMyLibraryLoaded(){ function tryBindEvent() { if (window.jQuery) { $(document).on("blur", "#someInput", function(){ console.log("Input blurred"); }); } else { // 每隔50ms检查一次,直到jQuery加载完成 setTimeout(tryBindEvent, 50); } } tryBindEvent(); } // 原有加载逻辑不变 if (!window['jQuery']) { setTimeout(addjQuery); } if (!window['myLibrary']) { setTimeout(addMyLibrary); } function addjQuery() { const script = document.createElement('script'); script.src = 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js'; script.onload = onjQueryLoaded; document.body.appendChild(script); } function addMyLibrary() { const script = document.createElement('script'); script.src = 'https://jrags/myLibrary.min.js'; script.onload = onMyLibraryLoaded; document.body.appendChild(script); } function onjQueryLoaded(){ console.log('jquery loaded successfully') }
关于await的使用
完全可以用await解决这个问题,方案1就是典型的应用:把脚本加载的异步操作包装成Promise,通过await强制等待jQuery加载完成后,再加载myLibrary,确保后续代码执行时依赖已经就绪。
内容的提问来源于stack exchange,提问作者Jeremy Ragsdale
相关产品推荐
相关产品推荐

