jQuery的getScript()上的回调是不可靠的还是我做错了什么?

我正在使用以下一些脚本来加载另一个:

$.getScript("CAGScript.js", function () { try { CAGinit(); } catch(err) { console.log(err); } }); 

我们的想法是$ .getScript加载脚本,然后在完成后执行回调。 CAGInit()是一个存在于CAGScript.js的函数。

问题是,大约一半的时间, CAGInit()不会触发(在任何浏览器中)。 登录到Firebug控制台会报告它未定义。 其余的时间它完美地运作。

有没有人有任何想法我做错了什么?

谢谢。

如果文件保存在同一个域中,那么jQuery将使用XHR检索其内容,然后全局“评估”它。 这应该工作正常,但如果你遇到问题,那么我建议使用注入脚本标记的替代方法。 不幸的是,jQuery没有公开这个function所以你必须自己做:

 var script = jQuery('').attr('src', 'CAGSCript.js').appendTo('head'); var timer = setInterval( function(){ if (window.CAGInit !== undefined) { clearInterval(timer); script.remove(); // Do your stuff: CAGInit(); } }, 200); 

最好把它抽象成一个函数; 以上只是一个例子……

我注意到FF 3.6的问题。

解决方案是同步加载脚本。

正如jQuery文档中提到的 ,getScript是以下的简写:

 $.ajax({ url: url, dataType: 'script', success: success }); 

如果我使用以下代替getScript,一切正常:

 $.ajax({ url: url, dataType: 'script', success: success, async: false }); 

只是想提供一些关于这个问题的见解。 如果您正在加载的代码中出现错误,并且(至少在使用jQuery 1.7.1的Chrome上)错误将被吞没,则不会触发回调。 我发现在我加载的代码中有一个来自自动完成的杂散花括号,并且回调函数没有触发。 此处的间歇性行为可能是由更改测试之间加载的代码引起的。

刚刚在firefox上遇到了同样的问题,用一点点黑客解决了它。

将它应用于您的示例:

 $.getScript("CAGScript.js", function (xhr) { try { CAGinit(); } catch(err) { eval(xhr); CAGinit(); } }); 

基本上强制评估XHR响应,如果它自己没有这样做。

我也在Chrome上遇到过这个问题。 jQuery偶尔会调用成功回调,好像一切都好,但脚本实际上并没有正确加载。 在我们的例子中,解决方案是简单地从信任jQuery改变:

  

信任浏览器:

   

我一次又一次地发现“jQuery == less edge = = less bug”。 而且通常代码也更易读!

为了确保在调用CAGinit函数之前CAGScript.js是LOADED和EXECUTED,最可靠的方法是在CAGScript.js中调用函数。

CAGScript.js:

 ... /* your code */ function CAGinit(){ ... } ... /* last line */ CAGinit(); 

然后,在你的主文件中调用getScript():

 $.getScript("CAGScript.js"); 

是的,我也发现在FireFox中getScript不可靠,在脚本下载和/或执行之前触发了回调。 (使用JQuery 1.41和FireFox 3.6。问题似乎并不影响IE,Chrome或Opera。)

我还没有做过大量的测试,但似乎只发生在某些特定的脚本上……不确定原因。

RaYell的建议不起作用,因为即使脚本尚未被评估,getScript也会报告成功。 在大多数情况下,Pieter的建议导致代码被评估两次,效率低下并且可能导致错误。

这种替代方案似乎适用于getScript没有的地方。 请注意,它似乎是添加了一个SCRIPT DOM元素,而getScript则是XHR。

http://www.diveintojavascript.com/projects/sidjs-load-javascript-and-stylesheets-on-demand

我想你可以从检查回调函数的testStatus开始,以确保脚本真正加载。 回调函数有两个参数,你可以在jQuery Docs上找到更多的参数

 $.getScript("CAGScript.js", function (data, textStatus) { if (textStatus === "success") { try { CAGinit(); } catch(err) { console.log(err); } } else { console.log("script not loaded"); } }); 

我希望在JS中使用PHP实现与auto_load类似的东西,典型的解决方案是在所有函数上使用try-catch。当函数丢失时,我们跳转到下载它的库。我的解决方案来自Pieter解决方案,如下所示:

 function CheckUserPW(username,password){ try{ loginCheckUserPW(username,password); } catch(err) { $.getScript('login.js', function(xhr){ eval(xhr); loginCheckUserPW(username,password); }); } } 

看起来像jQuery现在处理跨域和相同的域请求就好了。 对于跨域请求,它将添加脚本标记并订阅错误和加载事件并适当调用完成和错误回调,只有在请求失败时才会出错,评估脚本的错误仍将被视为成功请求有关。 对于同源,它将执行XHR请求,然后执行globalEval,一旦完成,调用完成的回调,如果在此过程中任何失败,它将调用您的错误回调。

使用XHR有一些问题,它打破了调试器,源映射,它依赖于globalEval,它与ContentSecurityPolicy有问题。 为了保持一致性,我们只需在加载脚本时添加脚本标记。

var scriptElement = $("

如果您想在本文中没有jQuery搜索动态导入脚本的情况下执行此操作

希望这可以帮助。

我的方式是

 setTimeout(function(){ $.getScript( "CAGScript.js"); }, 2000); 

同样的问题,当我们想要更新$ scope中的数据时,我们也面临角度,并且通过在角度中以相同的方式使用$ timeout来解决它…