编写Javascript库:Asynch加载时序问题

时间:2015-08-09 22:23:50

标签: javascript loading timing

在我写的JS库中,我有loadScript func:

function loadScript(src, callback) {
  var script = document.createElement('script');
  script.src = src;
  // script.type = "text/javascript";
  // script.async = false;
  if (typeof callback !== 'undefined') {
    script.onload = function () {
      callback();
    };
  }
  document.head.appendChild(script);
}

在主js文件中,我使用它在加载主js文件后动态加载依赖项,在其回调中启动JSLib对象。

  loadScript(baseUrl + '/dependencies/you-load-me-long-time.js', function() {
     window.JSLib = true;
   }

然后我有一个调用此库的网页。

var jsLib = new JSLib({...});

我遇到的问题是 - 在加载此JS库的网页中,浏览器抱怨JSLib未定义,因为依赖文件you-load-me-long-time.js尚未完成加载网页中的脚本被执行。

现在似乎有效的解决方法是,在网页中,我将启动代码包装在$(window).load(function() {});调用中。

有什么办法可以解决这个时间问题吗?例如:"阻止"加载网页的其余部分,直到加载JSLib(听起来不是一个好主意)等等......

1 个答案:

答案 0 :(得分:1)

只有两种方法可以创建通过JS加载的阻塞动态脚本,这两种方法都非常不受欢迎。

  1. 如果仍在分析文档,则可以使用document.write()在当前文档位置插入<script>标记。然后将同步解析和加载。

  2. 如果脚本资源与文档位于同一源,则可以使用同步Ajax调用获取脚本,然后评估脚本。

  3. 由于这两者都不是特别需要,通常的解决方法是将回调表示回到脚本的调用者,以便他们可以在异步操作完成时参与并将其代码放入异步中回调。

    var jsLib = new JSLib({...}, function() {
        // put code here that uses the jsLib because now it is loaded
    });
    

    由于这个混乱的原因,使构造函数的完成成为异步操作通常不是一个好习惯。它使对象的使用变得非常复杂。

    更常见的是让构造函数只创建对象的shell,然后需要.load(fn)方法调用来实际加载它。这可能会减少来电者误导图书馆的可能性。

    var jsLib = new JSLib({....});
    jsLib.load(function(err) {
        if (err) {
            // error loading the library
        }  else {
            // library is loaded now and all functionality can be used
        }
    });
    

    仅供参考,您使用$(window).load()的想法不是一个好主意。该方法可能会意外地工作,因为它会延迟时间,直到您的脚本加载,但窗口加载事件不会特别等到动态加载的脚本加载,因此它不是等待您的脚本的可靠方法。 / p>