【问题标题】:jQuery getScript load vs executionjQuery getScript 加载与执行
【发布时间】:2014-02-07 09:59:15
【问题描述】:

getScript docs 表示成功回调:

“一旦脚本被加载但不一定执行,回调就会被触发。”

但在我的测试中,这似乎不是真的。对于具有以下内容的主机页面:

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 source 中,globalEval 函数正在立即调用脚本:

converters: {
    "text script": function( text ) {
        jQuery.globalEval( text );
        return text;
    }
}

那么文档错了吗?如果它们是正确的,那么在什么特定情况下成功回调会在脚本执行之前触发

【问题讨论】:

  • 您可以将您的问题和降价提交给github.com/jquery/api.jquery.com/issues 吗? :)
  • 文档肯定是错误的,谢谢提醒:)
  • 谢谢,提交的 github 问题:github.com/jquery/api.jquery.com/issues/420
  • 对于它的价值:我的一个应用程序正好遭受这种竞争条件。外部脚本除了设置一个全局变量什么都不做,几乎总是在回调之前执行。但是偶尔它不会,并且当回调运行时全局变量仍然是undefined,导致应用程序崩溃。我想知道是否有一种可靠的方法可以延迟回调的执行,直到脚本执行完毕......

标签: jquery


【解决方案1】:

我在 1.7.1 版本的 jQuery 中遇到过这个问题。在 2.1.0 版本之前,前面提到的 $.globalEval() 函数是使用臭名昭著的 eval() 的间接调用来在全局环境中运行代码。

所以这肯定是以前的问题。

在 2.1.0 版本中,由于间接 eval 调用的某些缺失,他们已切换到脚本插入。如果您愿意,可以在此处找到更多信息。

http://perfectionkills.com/global-eval-what-are-the-options/

在带有脚本插入的较新实现中,这一行正在发挥作用

context.head.appendChild( script ).parentNode.removeChild( script );

除非存在一些奇怪的底层浏览器机制,否则似乎脚本必须立即执行,然后从 DOM 树中删除。

【讨论】:

    【解决方案2】:

    这是对原始发布者提交的GitHub issue 的回复的引用:

    $.getScript("https://platform.twitter.com/widgets.js").done(..) 与一些 twitter 媒体将触发完成的代码,而无需等待执行发生。

    因此,文档似乎是正确的,尽管可能不像人们希望的那样具有描述性。

    【讨论】:

    • 嗯...我想看看那个代码。我强烈怀疑 Twitter 小部件中存在超时或某些异步行为。换句话说,脚本已经被执行,并且任何后来的相关代码都在事件循环中发生。这意味着成功回调可能会在某些辅助操作完成之前触发。
    【解决方案3】:

    据我所知,查看源代码,我同意您的结论,即承诺应该始终在脚本执行后解决。

    但是我的记忆告诉我,在众多浏览器 jQuery 1.x 支持(s|ed) 之一中注入&lt;script&gt; 标签有些奇怪。问题浏览器在脚本执行之前触发了加载的回调,或者我们不会在文档中添加关于它的注释。

    我很确定 $.getScript 的实现从那时起已经改变,文档中的问题行不再相关,无论哪种方式,我们都需要在 jQuery 核心团队面前提出问题。你真的应该在github 上打开一个问题 - 随时抄送@gnarf。

    【讨论】:

      猜你喜欢
      • 2013-01-11
      • 1970-01-01
      • 2011-08-13
      • 1970-01-01
      • 2013-08-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多