提问人:Ben 提问时间:1/18/2014 更新时间:3/26/2020 访问量:6778
jQuery getScript 加载与执行
jQuery getScript load vs execution
问:
getScript 文档对 success 回调是这样说的:
“脚本加载后会触发回调,但不一定执行。”
但在我的测试中,这似乎不是真的。对于具有以下功能的主机页面:
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支持的众多浏览器之一中注入标签有些奇怪。有问题的浏览器在脚本执行之前触发了加载的回调,否则我们不会在文档中添加有关它的注释。<script>
(s|ed)
我很确定从那时起,它的实现已经发生了变化,文档中的问题行不再相关,无论哪种方式,我们都需要将问题摆在jQuery核心团队面前。你真的应该在 github 上提出一个问题 - 请随时抄送@gnarf。$.getScript
这是原始发帖人对 GitHub 问题的回应中的一句话:
$.getScript("https://platform.twitter.com/widgets.js").done(..)
对于某些 Twitter,媒体将触发完成的代码,而无需等待执行发生。
因此,文档似乎是正确的,尽管可能不像人们希望的那样具有描述性。
评论
我在 jQuery 的 1.7.1 版本中遇到了这个问题。在 2.1.0 版本之前,上述函数使用间接调用 infamous 在全局环境中运行代码。$.globalEval()
eval()
所以这在以前肯定是一个问题。
在版本 2.1.0 中,由于缺少某些间接 eval 调用,它们已切换到脚本插入。如果您愿意,可以在此处找到更多信息。
http://perfectionkills.com/global-eval-what-are-the-options/
在带有脚本插入的较新实现中,这一行正在发挥神奇的作用
context.head.appendChild( script ).parentNode.removeChild( script );
除非存在一些奇怪的底层浏览器机制,否则脚本似乎必须立即执行,然后才能从 DOM 树中删除。
评论
undefined