【问题标题】:asynchronous javascript loading/executing异步 javascript 加载/执行
【发布时间】:2011-06-05 15:13:37
【问题描述】:

在这篇 asynchronous .js file loading syntax 的帖子中,有人说,“如果存在 async 属性,那么脚本将在可用时立即异步执行。”

(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 */

我的问题是,“脚本将异步执行”是什么意思?此脚本是否会在与页面中其他 javascript 不同的线程中执行?如果是,我们是否应该担心两个线程中的同步问题?

谢谢。

【问题讨论】:

  • 这个脚本一被解析就被执行,所以我不确定仅仅使用<script>标签和设置异步属性有什么区别。
  • 我认为脚本应该由var fs = document.getElementByTagName('script')[0];fs.parentNode.insertBefore(s, fs);添加。这样,您就可以确定在完成文档的第一次解析之前不会解析脚本。

标签: javascript


【解决方案1】:

通常,当您将外部脚本添加到 HTML 文档时,需要先下载并执行该脚本,然后才能在页面上执行任何其他操作。换句话说,脚本块。如果要下载多个脚本,这可能需要很长时间。

但是当您异步加载脚本时,它不会阻塞。可以加载页面的其余部分,并且可以在下载异步脚本时执行其他脚本。这使页面加载速度更快,但这也意味着您无法确定异步脚本何时执行。因此,您不能只开始使用异步脚本中的函数和对象。您必须等待并检查异步脚本是否加载。

例子:

script1.js

var foo = "bar";

script2.js

alert(foo);

doc1.html

<script type="text/javascript" src="script1.js"></script>
<script type="text/javascript" src="script2.js"></script>

结果:“条”

doc2.html

<script type="text/javascript" src="script1.js" async="true"></script>
<script type="text/javascript" src="script2.js"></script>

结果:“bar”或未定义,取决于 script1.js 是否已加载。

不过,无需担心线程。一个脚本一个接一个地执行,但绝不会同时执行。只是执行顺序变得不可预测。

【讨论】:

  • 您可以使用defer 关键字代替async,以确保只要您的脚本不修改DOM,就可以保持顺序
【解决方案2】:

它不会在不同的线程上执行。在这种情况下,您不必担心线程同步。

稍后,在您当前的调用堆栈展开后,myfile.js 的下载将完成。之后浏览器和 js 框架会执行你的脚本。

【讨论】:

    【解决方案3】:

    已异步下载,而不是异步执行。另外,下载完成后也不一定会执行。

    【讨论】:

    • 您能进一步扩展吗?为什么它在完成时会执行或不执行?你的意思是会延迟吗?
    【解决方案4】:
      (function(doc, script) {
        var js, 
            fjs = doc.getElementsByTagName(script)[0],
            add = function(url, id) {
                if (doc.getElementById(id)) {return;}
                js = doc.createElement(script);
                js.src = url;
                id && (js.id = id);
                fjs.parentNode.insertBefore(js, fjs);
            };
    
        // Google Analytics
        add(('https:' == location.protocol ? '//ssl' : '//www') + '.google-analytics.com/ga.js', 'ga');
        // Google+ button
        add('https://apis.google.com/js/plusone.js');
        // Facebook SDK
        add('//connect.facebook.net/en_US/all.js', 'facebook-jssdk');
        // Twitter SDK
        add('//platform.twitter.com/widgets.js', 'twitter-wjs');
    }(document, 'script'));
    

    来源:https://css-tricks.com/thinking-async/

    【讨论】:

      猜你喜欢
      • 2011-05-14
      • 2011-08-29
      • 2012-11-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多