jQuery getScript加载与执行
getScript文档说明成功回调:
“一旦脚本加载但未必执行,则会触发回调。”
但在我的测试中似乎并不属实。 对于包含以下内容的主页:
var startTime = new Date(); $.getScript("test.js") .done(function( script, textStatus ) { console.log( textStatus ); console.log( "Done callback executing now.") }) .fail(function( jqxhr, settings, exception ) { console.log("error." ); });
加载以下“test.js”脚本,该脚本占用UI 5秒钟:
console.log("ajaxed script starting to execute."); var newTime = new Date(); while (newTime - startTime < 5000) { newTime = new Date(); } console.log("elapsed time", newTime - startTime); console.log("ajaxed script finished executing.");
在FF和Chrome中产生相同的可预测控制台输出:
ajaxed script starting to execute. elapsed time 5000 ajaxed script finished executing. success Done callback executing now.
换句话说,在加载和执行加载的脚本之前,成功回调不会触发。 这似乎是因为在jQuery 源代码中 ,globalEval函数立即调用脚本:
converters: { "text script": function( text ) { jQuery.globalEval( text ); return text; } }
那些文档错了吗? 如果它们是正确的,那么在脚本执行之前 ,成功回调会在什么特定情况下触发?
从我所看到的来源,我同意你的结论,承诺应该总是 在脚本执行后解决。
但是我的记忆告诉我,在许多浏览器jQuery 1.x支持(s|ed)
之一中注入标签有一些奇怪之处。 问题浏览器在脚本在某个时刻执行之前触发了加载的回调,或者我们不会在文档中添加关于它的说明。
我非常确定$.getScript
的实现$.getScript
起已经发生了变化,文档中的问题行不再相关,无论我们需要在jQuery核心团队面前提出问题。 你真的应该在github上打开一个问题 - 随意cc @gnarf。
这是对原始海报提交的对GitHub问题的回复的引用:
$.getScript("https://platform.twitter.com/widgets.js").done(..)
与一些Twitter媒体将触发完成的代码而不等待执行发生。
因此,文档似乎是正确的,尽管可能不像人们希望的那样具有描述性。
我在1.7.1版本的jQuery中遇到过这个问题。 在版本2.1.0之前, $.globalEval()
的$.globalEval()
函数使用臭名昭着的eval()
间接调用来在全局环境中运行代码。
所以这肯定是一个问题。
在版本2.1.0中,由于缺少间接eval调用,它们已切换到脚本插入。 如果您愿意,可以在此处找到更多信息。
http://perfectionkills.com/global-eval-what-are-the-options/
在使用脚本插入的较新实现中,这一行正在发挥作用
context.head.appendChild( script ).parentNode.removeChild( script );
除非有一些奇怪的底层浏览器机制,否则在从DOM树中删除之前, 必须立即执行脚本。