【问题标题】:Why did wrapping my JavaScript library in an anonymous function fix my race condition?为什么将我的 JavaScript 库包装在匿名函数中修复了我的竞争条件?
【发布时间】:2011-10-05 03:07:39
【问题描述】:

问题:为什么将我的 JavaScript 库包装在匿名函数中可以修复我的竞争条件?

注意:我也对同步和异步加载外部 JavaScript 资源的好解决方案的评论感兴趣。

我正在从事一个涉及使用 crossrider 编写浏览器扩展的项目。如果您不熟悉使用 JavaScript 实现的跨骑手扩展,那么您有一个可以与应用程序页面通信的背景页面。应用页面可以与每个打开的选项卡一起运行,并且可以操作 DOM。我计划在用户请求打开时远程加载大部分扩展代码。最近,当我向页面referencing Raphael 添加脚本标签时遇到了竞争条件,然后我构建了out of graffle

据我了解,如果页面加载时已经存在这些脚本标签,那么执行将同步进行,尽管由于我附加了脚本标签,因此执行是异步进行的。这是大多数人似乎遇到的相反问题。搞砸了它,我了解到将我的代码 graffle 代码包装在一个匿名函数中修复了我的竞争条件。为什么?我在wrapping whole Javascript files in anonymous functions 上阅读了这篇文章,这似乎与比赛条件无关。

我的电话号码:

var scriptsToLoad   = [ "http://example/Scripts/lib/raphael.js",
                "http://example/Scripts/lib/graffle.js",
                "http://example/Scripts/lib/log4javascript.js"];

for(var i in scriptsToLoad) {
    (function(){
        $("head")
            .append($("<script></script>")
                .attr("type", "text/javascript")
                .attr("src", scriptsToLoad[i]));
    })()
}

【问题讨论】:

  • 可能与您的问题无关:如果您使用for..in 遍历一个数组,您还会遇到length 属性。检查您是否将&lt;script&gt; 元素附加到src="3"
  • 您应该使用for,而不是for..in(但您可以使用if(scriptsToLoad.hasOwnProperty(i)){} 包装器。
  • @AtesGoral 这不是真的; length 属性不可枚举。您的建议仍然是合理的,仅出于其他两个原因:性能,以及有人在 Array 原型中添加了其他垃圾的可能性。
  • 仅仅因为竞争条件不再有明显的症状并不意味着它已被“修复”。您尝试“解决”问题的原因可能有多种,但除非您可以从 ecma 脚本标准或其他文档中找到一些理由,否则我不确定您如何确定竞争条件真的消失了。您是否在一系列浏览器中看到相同的结果?
  • 第二个 davmac 的评论。 根据定义,竞争条件的行为取决于运行时事件的确切交错,而不仅仅是代码所说的内容。有时会发生竞争条件错误是很常见的,有时不会发生。我的荣誉主管曾经说过,不可能从程序中调试竞争条件,您必须知道您的设计确保没有竞争条件。

标签: javascript asynchronous anonymous-function race-condition


【解决方案1】:

关于您的问题,我认为没有为 &lt;script /&gt; 标签的加载和评估顺序设置任何特定标准;很容易引入竞争条件。

关于 (a) 同步脚本加载,使用 jQuery,请执行以下操作:

var scriptsToLoad = [
    "http://example/Scripts/lib/raphael.js",
    "http://example/Scripts/lib/graffle.js",
    "http://example/Scripts/lib/log4javascript.js"
];

$.each(scriptsToLoad, function (index, script) {
    $.ajax({
        url      : script,
        async    : false,
        dataType : 'script'
    });
});

【讨论】:

  • 关键是将async标志设置为false,使每个脚本的请求同步。
  • dataType 标志为script 时,jQuery 将在脚本加载时自动全局评估脚本。如果您可以异步加载脚本,只需使用$.getScript(script);
  • 只是一个注释,但是 not 动态添加到 DOM 的脚本标签实际上会阻塞,并按顺序加载。
  • 我真的不知道将 &lt;script /&gt; 标签附加到闭包内的文档应该完成什么。在我看来,好像有人注意到这样做与以正确顺序加载脚本之间存在正相关关系,但未能确定因果关系并做出了一些不正确的假设。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-06
  • 2015-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多