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 Undefined,Null类型和NaN值区别
Oct 22 Javascript
跨域表单提交状态的变相判断代码
Nov 12 Javascript
javascript中常用编程知识
Apr 08 Javascript
谷歌地图打不开的解决办法
Aug 07 Javascript
Javascript基础教程之数据类型 (布尔型 Boolean)
Jan 18 Javascript
jQuery抛物线运动实现方法(附完整demo源码下载)
Jan 08 Javascript
JS实现鼠标框选效果完整实例
Jun 20 Javascript
微信小程序左滑删除效果的实现代码
Feb 20 Javascript
ReactNative页面跳转Navigator实现的示例代码
Aug 02 Javascript
微信小程序开发常见问题及解决方案
Jul 11 Javascript
微信小程序绘制图片发送朋友圈
Jul 25 Javascript
vue获取data数据改变前后的值方法
Nov 07 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
destoon实现VIP排名一直在前面排序的方法
2014/08/21 PHP
JavaScript DOM学习第一章 W3C DOM简介
2010/02/19 Javascript
javascript制作的cookie封装及使用指南
2015/01/02 Javascript
vue+axios新手实践实现登陆的示例代码
2018/06/06 Javascript
微信小程序canvas拖拽、截图组件功能
2018/09/04 Javascript
Angularjs实现数组随机排序的方法
2018/10/02 Javascript
纯javascript实现选择框的全选与反选功能
2019/04/08 Javascript
JQuery实现简单的复选框树形结构图示例【附源码下载】
2019/07/16 jQuery
使用Vue CLI创建typescript项目的方法
2019/08/09 Javascript
HTML+JavaScript实现扫雷小游戏
2019/09/30 Javascript
vue使用video插件vue-video-player的示例
2020/10/03 Javascript
ES6中的类(Class)示例详解
2020/12/09 Javascript
Python爬虫:通过关键字爬取百度图片
2017/02/17 Python
Python Learning 列表的更多操作及示例代码
2018/08/22 Python
Python一句代码实现找出所有水仙花数的方法
2018/11/13 Python
Python之修改图片像素值的方法
2019/07/03 Python
python字典嵌套字典的情况下找到某个key的value详解
2019/07/10 Python
python实现比对美团接口返回数据和本地mongo数据是否一致示例
2019/08/09 Python
Python对接支付宝支付自实现功能
2019/10/10 Python
python实现遍历文件夹图片并重命名
2020/03/23 Python
pandas数据选取:df[] df.loc[] df.iloc[] df.ix[] df.at[] df.iat[]
2020/04/24 Python
Python web如何在IIS发布应用过程解析
2020/05/27 Python
关于Theano和Tensorflow多GPU使用问题
2020/06/19 Python
利用HTML5 Canvas API绘制矩形的超级攻略
2016/03/21 HTML / CSS
怎样实现H5+CSS3手指滑动切换图片的示例代码
2019/05/05 HTML / CSS
伦敦一家西班牙童装精品店:La Coqueta
2018/02/02 全球购物
俄罗斯园林植物网上商店:Garshinka
2020/07/16 全球购物
公司营业员的自我评价
2014/03/04 职场文书
遗体告别仪式主持词
2014/03/20 职场文书
《地震中的父与子》教学反思
2014/04/10 职场文书
2014各大专业毕业生自我评价
2014/09/17 职场文书
暑期实践个人总结
2015/03/06 职场文书
制定企业培训计划的五大要点!
2019/07/10 职场文书
解决thinkphp6(tp6)在状态码500下不报错,或者显示错误“Malformed UTF-8 characters”的问题
2021/04/01 PHP
JS前端轻量fabric.js系列之画布初始化
2022/08/05 Javascript