JavaScript文件的同步和异步加载的实现代码


Posted in Javascript onAugust 19, 2017

对于JS文件的引用,尽管当前有不少框架和工具(比如webpack,commonjs,requiresjs等)都做了很好的处理。但是抛开这些框架,了解原生的加载方式还是不无裨益。本文简述一些js文件的同步和异步加载方式。

同步加载

可在html文件里以<script>标签插入,这是初学时最基本的方式。

准备两个js文件如下:

calc1.js

console.log('calc1 loading begin')

function add(...args) {
  return args.reduce((currentTotal, i) => currentTotal + i, 0);
}
console.log('calc1 loading end')

calc2.js

console.log('calc2 loading begin')

console.log(add(1,2,3))

console.log('calc2 loading end')

calc2.js 是依赖calc1.js的。

html文件如下:

<body>

  <script src="calc1.js">
  </script>
  
  <script src="calc2.js">
  </script>
</body>

这种方式下,文件加载是同步的。即calc1.js加载完成后,才加载calc2.js,所以保证了calc2.js总能正确地调用calc1里的add函数。在Chrome里的调试结果如下:

JavaScript文件的同步和异步加载的实现代码

但同步加载的缺点也明显,如果有多个文件的时候,全部加载时间会很长,而且阻塞用户界面响应。

通过Script Element异步加载

异步加载的优点是,能够同时加载多个js文件,而且由于是异步,不会阻塞用户界面,用户体验好。当然缺点是,不能保证有依赖关系的文件的加载顺序。

html 代码

<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <script type="text/javascript">
    var script1 = document.createElement('script');
    script1.src='calc1.js';
    script1.type='text/javascript';

    var script2 = document.createElement('script');
    script2.src='calc2.js';
    script2.type='text/javascript';

    document.getElementsByTagName('head')[0].appendChild(script1).appendChild(script2);
  </script>
</head>

在Chrome里的调试结果有时候能正确的输出如下:

JavaScript文件的同步和异步加载的实现代码

但有时候由于clac1.js没有被先加载,calc2.js执行时会报错。

JavaScript文件的同步和异步加载的实现代码

那么我们就得需要解决加载顺序问题,保证calc1.js先加载。

<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <script type="text/javascript">
    function loadScript(file, callbackFn) {
      var script = document.createElement('script');
      script.src= file;
      script.type='text/javascript';
      // 监听onload时间,当前js文件加载完成后,再加载下一个
      script.onload = callbackFn;
      document.getElementsByTagName('head')[0].appendChild(script)
    }
    
    loadScript('calc1.js', function () {
      loadScript('calc2.js');
    } );

  </script>
</head>

这样就能永远输出正确结果了。

通过 AJAX 加载JS文件
 

<script>
    function loadScript(file, callbackFn) {
      var xhr = new XMLHttpRequest();
      xhr.open('get', file, true);
      // for IE
      if (xhr.onreadystatechange) {
        xhr.onreadystatechange = function () {
          console.log(xhr.readyState, xhr.status);
          if (xhr.readyState == 4) {
            if (xhr.status >= 200 && xhr.status < 300 || xhr.status == 304) {
              insertScriptText(xhr.responseText);
              if (callbackFn) {
                callbackFn();
              }
            }
          }
        }
      } else {
        xhr.onload = function () {
          insertScriptText(xhr.responseText);
          if (callbackFn) {
            callbackFn();
          }
        }
      }
      xhr.send(null);
    }

    function insertScriptText(scriptText) {
      var script = document.createElement('script');
      script.type = 'text/javascript';
      script.text = scriptText;
      document.body.appendChild(script);
    }

    loadScript('calc1.js', function () {
      loadScript('calc2.js');
    });

  </script>

也能正确的输出结果。

JavaScript文件的同步和异步加载的实现代码

总结

如果是单一或少数js文件,可以在html body的最后插入script标签,以同步方式加载。Webpack其实也是把多个js文件合并称一个,然后在body插入script引用。

如果是多个js文件,建议异步加载,以避免阻塞界面渲染,也缩短整体加载时间。本文介绍了script element和Ajax两种方式,并且对于有依赖关系的文件加载顺序,也做了实例。请参考 https://github.com/JackieGe/Js-Learn/tree/master/ch1-async-loading

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript学习基础笔记之DOM对象操作
Nov 03 Javascript
jquery 延迟执行实例介绍
Aug 20 Javascript
jQuery中bind与live的用法及区别小结
Jan 27 Javascript
js实现遮罩层划出效果是生成div而不是显示
Jul 29 Javascript
javascript实现带节日和农历的日历特效
Feb 01 Javascript
javascript判断并获取注册表中可信任站点的方法
Jun 01 Javascript
jquery实现的伪分页效果代码
Oct 29 Javascript
Google 地图事件实例讲解
Aug 06 Javascript
如何利用JQuery实现从底部回到顶部的功能
Dec 27 Javascript
AngularJS Toaster使用详解
Feb 24 Javascript
jQuery实现的点击显示隐藏下拉菜单功能完整示例
May 17 jQuery
JavaScript实现队列结构过程
Dec 06 Javascript
深入理解ES6学习笔记之块级作用域绑定
Aug 19 #Javascript
深入理解ES6的迭代器与生成器
Aug 19 #Javascript
Mui使用jquery并且使用点击跳转新窗口的实例
Aug 19 #jQuery
Vue自定义事件(详解)
Aug 19 #Javascript
Vue内容分发slot(全面解析)
Aug 19 #Javascript
简单的网页广告特效实例
Aug 19 #Javascript
JavaScript 完成注册页面表单校验的实例
Aug 19 #Javascript
You might like
删除及到期域名的查看(抢域名必备哦)
2008/05/14 PHP
php命令行(cli)下执行PHP脚本文件的相对路径的问题解决方法
2015/05/25 PHP
PHP实现操作redis的封装类完整实例
2015/11/14 PHP
php提交表单时保留多个空格及换行的文本样式的方法
2017/06/20 PHP
javascript引用对象的方法
2007/01/11 Javascript
js直接编辑当前cookie的脚本
2008/09/14 Javascript
支持ie与FireFox的剪切板操作代码
2009/09/28 Javascript
Javascript处理DOM元素事件实现代码
2012/05/23 Javascript
纯javascript实现简单下拉刷新功能
2015/03/13 Javascript
jQuery封装的tab选项卡插件分享
2015/06/16 Javascript
javaScript实现滚动新闻的方法
2015/07/30 Javascript
Javascript简单实现面向对象编程继承实例代码
2015/11/27 Javascript
第二篇Bootstrap起步
2016/06/21 Javascript
简单理解vue中el、template、replace元素
2016/10/27 Javascript
微信小程序 定位到当前城市实现实例代码
2017/02/23 Javascript
Angular.Js中过滤器filter与自定义过滤器filter实例详解
2017/05/08 Javascript
JS实现数组简单去重及数组根据对象中的元素去重操作示例
2018/01/05 Javascript
swiper在angularjs中使用循环轮播失效的解决方法
2018/09/27 Javascript
前端面试知识点目录一览
2019/04/15 Javascript
简单了解前端渐进式框架VUE
2020/07/20 Javascript
Vue实现Header渐隐渐现效果的实例代码
2020/11/05 Javascript
Python入门之modf()方法的使用
2015/05/15 Python
同时安装Python2 &amp; Python3 cmd下版本自由选择的方法
2017/12/09 Python
PyQt5实现暗黑风格的计时器
2019/07/29 Python
浅谈PyQt5中异步刷新UI和Python多线程总结
2019/12/13 Python
python读取raw binary图片并提取统计信息的实例
2020/01/09 Python
纯CSS3代码实现switch滑动开关按钮效果
2016/08/30 HTML / CSS
html5教程实现Photoshop渐变色效果
2013/12/04 HTML / CSS
80年代复古T恤:TruffleShuffle
2018/07/02 全球购物
世界上最好的野生海鲜和有机食品:Vital Choice
2020/01/16 全球购物
逻辑链路控制协议
2016/10/01 面试题
经济学博士求职自荐信范文
2013/11/23 职场文书
公司联欢会主持词
2015/07/04 职场文书
纪念建国70周年演讲稿
2019/07/19 职场文书
mysql中整数数据类型tinyint详解
2021/12/06 MySQL
Java中的Kotlin 内部类原理
2022/06/16 Java/Android