【问题标题】:How can I block the execution of a script until another one is loaded?如何在加载另一个脚本之前阻止脚本的执行?
【发布时间】:2012-06-01 07:21:51
【问题描述】:

假设我从我的主机网页加载这些脚本:

<script src="http://www.mywebsite.com/widget/widget.js?type=normal" type="text/javascript"></script>
<script src="http://www.mywebsite.com/widget/widget.js?type=rotation" type="text/javascript"></script>

我只想在第一个完成后才执行第二个(完全;它可以包含异步函数)。

我该怎么做?

【问题讨论】:

  • 使用像 yepnope 这样的异步 javascript 加载器怎么样?

标签: javascript asynchronous load


【解决方案1】:

您已经做对了:脚本按照页面中的集成顺序执行,而不是加载。

编辑:正如 MaxArt 所指出的,这可能不是您想要的。他的回答很好。 但一般来说,您需要使用 javascript 常用模式和基于事件的逻辑来避免此类问题:

  • 让您的大部分文件只定义类和函数(其中一些将回调作为参数)
  • 有一个 main 文件启动它并调用一系列操作,异步性通过回调处理。

我的主要代码通常看起来(有点)像这样:

$(window).ready(function() {
    var myBigEngine = new BigEngine();
    myBigEngine.init(function(){
      // do other things, no need to add other layers as user events and ajax message callback will do the rest
    });
});

【讨论】:

  • markzzz 说它可以包含异步函数,也许是 XHR 请求。我猜他想等到他们完成加载。
  • @MaxArt 谢谢。我不明白 OP 真正想要什么。我会看看我是否有更聪明的说法,在相反的情况下我会删除我的答案。
【解决方案2】:

将整个脚本包装在一个函数中,如下所示:

(function(id) {
    var id = setInterval(function() {
        if (!window.doneLoading) return;
        clearInterval(id);

        // The whole script file goes here
        ...
    }, 50);
})();

setInterval 轮询(全局,抱歉)变量doneLoading。在第一个脚本中,您必须在异步函数完全加载时将 doneLoading 设置为 true 或任何其他非 false 值,比如在 AJAX 请求结束时可能?

编辑:既然我建议在脚本中添加一个全局变量,那么它也可以添加一个全局函数。因此,不要设置 setInterval 调用,而是将第二个脚本包装在一个函数中......但是像这样:

function doneLoading() {
        // The whole script file goes here
        ...
}

在第一个脚本文件中,在回调函数结束时,只需调用doneLoading()

【讨论】:

  • 做不到!脚本应该相同,所以 doneLoading() 可以具有相同的值...
【解决方案3】:

尝试将 defer="defer" 属性应用于第二个 &lt;script&gt; 声明,如

&lt;script src="http://www.mywebsite.com/widget/widget.js?type=rotation" type="text/javascript" defer="defer" &gt;&lt;/script&gt;

【讨论】:

    【解决方案4】:

    您可以将第二个脚本初始化函数放在 window.onload 事件中

    window.onload = function(){
    
    // call function from second script
    
    }
    

    或使用 jQuery

    $(function(){
    
    // call function from second script
    
    });
    

    您可以使用此功能添加第二个脚本

    function loadScript(src){
        var f=document.createElement('script');
        if(f){
            f.setAttribute("type","text/javascript");
            f.setAttribute("src",src);
            document.getElementsByTagName("head")[0].appendChild(f);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-13
      • 1970-01-01
      相关资源
      最近更新 更多