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 相关文章推荐
CLASS_CONFUSION JS混淆 全源码
Dec 12 Javascript
IE8 chrome中table隔行换色解决办法
Jul 09 Javascript
jquery获取input的value问题说明
Aug 19 Javascript
基于JQuery的简单实现折叠菜单代码
Sep 15 Javascript
jQuery :nth-child前有无空格的区别分析
Jul 11 Javascript
js定时器实例分享
Dec 20 Javascript
jQuery实现 上升、下降、删除、添加一行代码
Mar 06 Javascript
JQuery元素快速查找与操作
Apr 22 jQuery
微信小程序支付PHP代码
Aug 23 Javascript
vue-router的两种模式的区别
May 30 Javascript
vue + typescript + 极验登录验证的实现方法
Jun 27 Javascript
JavaScript实现省份城市的三级联动
Feb 11 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
Windows下的PHP5.0详解
2006/11/18 PHP
php下实现一个阿拉伯数字转中文数字的函数
2008/07/10 PHP
深入浅析yii2-gii自定义模板的方法
2016/04/26 PHP
向fckeditor编辑器插入指定代码的方法
2007/05/25 Javascript
jquery验证手机号码、邮箱格式是否正确示例代码
2013/07/28 Javascript
js实现星星打分效果的方法
2020/07/05 Javascript
javascript实现确定和取消提示框效果
2015/07/10 Javascript
jQuery左右滚动支持图片放大缩略图图片轮播代码分享
2015/08/26 Javascript
JavaScript基本的输出和嵌入式写法教程
2015/10/20 Javascript
浅析JS原型继承与类的继承
2016/04/07 Javascript
JavaScript中访问id对象 属性的方式访问属性(实例代码)
2016/10/28 Javascript
面试常见的js算法题
2017/03/23 Javascript
Vue2.0使用过程常见的一些问题总结学习
2017/04/10 Javascript
React + webpack 环境配置的方法步骤
2017/09/07 Javascript
Vue实现数字输入框中分割手机号码的示例
2017/10/10 Javascript
微信小程序表单验证form提交错误提示效果
2020/06/19 Javascript
puppeteer库入门初探
2019/01/09 Javascript
vue离开当前页面触发的函数代码
2020/09/01 Javascript
[00:32]2018DOTA2亚洲邀请赛出场——VP
2018/04/04 DOTA
[42:24]完美世界DOTA2联赛循环赛 LBZS vs DM BO2第一场 11.01
2020/11/02 DOTA
python数据类型_元组、字典常用操作方法(介绍)
2017/05/30 Python
Python简单实现的代理服务器端口映射功能示例
2018/04/08 Python
使用python爬取B站千万级数据
2018/06/08 Python
pygame实现非图片按钮效果
2019/10/29 Python
python使用HTMLTestRunner导出饼图分析报告的方法
2019/12/30 Python
python 从list中随机取值的方法
2020/11/16 Python
详解html5 shiv.js和respond.min.js
2018/01/24 HTML / CSS
品管员岗位职责
2013/11/10 职场文书
优秀团队获奖感言
2014/02/19 职场文书
读书活动总结范文
2014/04/26 职场文书
党的群众路线教育实践活动自我剖析材料
2014/10/08 职场文书
研讨会通知
2015/04/27 职场文书
2015年幼师工作总结
2015/04/28 职场文书
首席执行官观后感
2015/06/03 职场文书
利用Python网络爬虫爬取各大音乐评论的代码
2021/04/13 Python
app场景下uniapp的扫码记录
2022/07/23 Java/Android