异步 .js 文件加载语法

Posted

技术标签:

【中文标题】异步 .js 文件加载语法【英文标题】:asynchronous .js file loading syntax 【发布时间】:2011-02-15 23:48:30 【问题描述】:

我注意到异步加载 js 文件的语法似乎略有不同,我想知道两者之间是否有任何区别,或者它们的功能是否几乎相同。我猜它们的工作原理相同,但只是想确保一种方法由于某种原因不会比另一种更好。 :)

方法一

(function() 
    var d=document,
    h=d.getElementsByTagName('head')[0],
    s=d.createElement('script');
    s.type='text/javascript';
    s.src='/js/myfile.js';
    h.appendChild(s);
)(); /* note ending parenthesis and curly brace */

方法二(在 Facebook 的代码中看到)

(function() 
    var d=document,
    h=d.getElementsByTagName('head')[0],
    s=d.createElement('script');
    s.type='text/javascript';
    s.async=true;
    s.src='/js/myfile.js';
    h.appendChild(s);
()); /* note ending parenthesis and curly brace */

【问题讨论】:

【参考方案1】:

我对此进行了尝试,并为此创建了一个库,其中包括在脚本最终加载时触发回调的支持。

Sigma.async_script_load('http://example.com/underscore-min.js', '_', function() 
  _([1,2,3,2,3,1]).uniq();
);

https://github.com/ssoroka/sigma

【讨论】:

【参考方案2】:

我注意到的唯一区别是 Facebook 方法中的 s.async=true;

asyncdefer 属性是布尔属性,指示脚本应如何执行。

使用这些属性可以选择三种可能的模式。 如果 async 属性存在,则脚本将在可用时立即异步执行。 如果 async 属性不存在但 defer 属性存在,则脚本当页面完成解析时执行。如果两个属性都不存在,则在用户代理继续解析页面之前立即获取并执行脚本。

来源及延伸阅读:Whatwg.org html 5: The script element

至于优势,你可能想看看谷歌在去年 12 月是怎么说的:

Google Analytics Launches Asynchronous Tracking

【讨论】:

酷,谢谢。 s.asynch=true 在这种情况下不是毫无意义吗,因为脚本被注入到 head 标签中?至于括号上的语法: (function() ... )(); vs: (function() ... ()); - 那些几乎一样吗? @taber:是的,括号语法达到了相同的目标。即:函数被评估为函数表达式而不是函数语句。请参阅:***.com/questions/440739/… 和 ***.com/questions/1634268/…(尤其是最后一条评论)。 @taber:我不认为将它插入<head> 的事实有什么不同。 (但我没有参考或测试来支持这一点)。 异步属性是 HTML5 特性。括号无关紧要。他们是一样的。 jslint 更喜欢function()()) 感谢您添加 GA 链接。是的,看起来“异步”只是脚本的未来证明,以“正式”告诉浏览器(现在是 Firefox 3.6)异步加载脚本。谢谢!

以上是关于异步 .js 文件加载语法的主要内容,如果未能解决你的问题,请参考以下文章

BOM 基础语法

JS引擎线程的执行过程的三个阶段

加载socket.io.js时Node.js“未捕获的语法错误:意外的令牌<”

JS基础 Promise

ajax语法结构

JS异步编程,1/3