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 相关文章推荐
JS 文件本身编码转换 图文教程
Oct 12 Javascript
通过jQuery源码学习javascript(一)
Dec 27 Javascript
jquery隐藏标签和显示标签的实例
Nov 11 Javascript
javascript的渐进增强与平稳退化浅谈
Nov 12 Javascript
jquery.cookie.js用法实例详解
Dec 25 Javascript
jQuery实现验证年龄简单思路
Feb 24 Javascript
jQuery+ajax简单实现文件上传的方法
Jun 03 Javascript
jquery对Json的各种遍历方法总结(必看篇)
Sep 29 Javascript
Base64(二进制)图片编码解析及在各种浏览器的兼容性处理
Feb 09 Javascript
浅谈Angular2 ng-content 指令在组件中嵌入内容
Aug 18 Javascript
vue实现学生录入系统之添加删除功能
Jul 11 Javascript
JS浅拷贝和深拷贝原理与实现方法分析
Feb 28 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
十天学会php之第九天
2006/10/09 PHP
CentOS下PHP安装Oracle扩展
2015/02/15 PHP
php中array_fill函数的实例用法
2021/03/02 PHP
JavaScript学习笔记之获取当前目录的实现代码
2010/12/14 Javascript
jquery 事件冒泡的介绍以及如何阻止事件冒泡
2012/12/25 Javascript
javascript之典型高阶函数应用介绍二
2013/01/10 Javascript
简单时间提示DEMO从0开始一直进行计时
2013/11/19 Javascript
判断文档离浏览器顶部的距离的方法
2014/01/08 Javascript
完美兼容各大浏览器获取HTTP_REFERER方法总结
2014/06/24 Javascript
原生JavaScript生成GUID的实现示例
2014/09/05 Javascript
JavaScript中setUTCFullYear()方法的使用简介
2015/06/12 Javascript
JavaScript去除数组里重复值的方法
2015/07/13 Javascript
ichart.js绘制虚线、平均分虚线效果的实现代码
2016/05/05 Javascript
jQuery简单验证上传文件大小及类型的方法
2016/06/02 Javascript
jQuery层次选择器用法示例
2016/09/09 Javascript
详解Node.js开发中的express-session
2017/05/19 Javascript
实战node静态文件服务器的示例代码
2018/03/08 Javascript
使用vue-router切换页面时,获取上一页url以及当前页面url的方法
2019/05/06 Javascript
微信小程序之下拉列表实现方法解析(附完整源码)
2019/08/23 Javascript
node.js使用 http-proxy 创建代理服务器操作示例
2020/02/10 Javascript
Python获取邮件地址的方法
2015/07/10 Python
python如何读写json数据
2018/03/21 Python
Python生成短uuid的方法实例详解
2018/05/29 Python
Python实现针对json中某个关键字段进行排序操作示例
2018/12/25 Python
Python递归实现打印多重列表代码
2020/02/27 Python
python的Jenkins接口调用方式
2020/05/12 Python
Pycharm创建python文件自动添加日期作者等信息(步骤详解)
2021/02/03 Python
意大利香水和彩妆护肤品购物网站:Ditano
2017/08/13 全球购物
Stuarts London美国/加拿大:世界领先的独立男装零售商之一
2019/03/18 全球购物
双十佳事迹材料
2014/01/29 职场文书
大学生先进个人主要事迹材料
2015/11/04 职场文书
中秋节英文祝福语句(14句)
2019/09/11 职场文书
Windows10下安装MySQL8
2021/04/06 MySQL
nginx反向代理配置去除前缀案例教程
2021/07/26 Servers
把77A收信机改造成收音机
2022/04/05 无线电
Vscode中SSH插件如何远程连接Linux
2022/05/02 Servers