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 相关文章推荐
禁止JQuery中的load方法装载IE缓存中文件的方法
Sep 11 Javascript
jQuery源码分析-01总体架构分析
Nov 14 Javascript
JavaScript中的property和attribute介绍
Dec 26 Javascript
javascript+xml实现简单图片轮换(只支持IE)
Dec 23 Javascript
js实现有时间限制消失的图片方法
Feb 27 Javascript
javascript自定义in_array()函数实现方法
Aug 03 Javascript
JavaScript实现节点的删除与序号重建实例
Aug 05 Javascript
AngularJS学习第二篇 AngularJS依赖注入
Feb 13 Javascript
Vue.js中组件中的slot实例详解
Jul 17 Javascript
Vue2.X 通过AJAX动态更新数据
Jul 17 Javascript
JavaScript判断对象和数组的两种方法
May 31 Javascript
Openlayers实现点闪烁扩散效果
Sep 24 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平台中配置nginx+php环境
2015/12/06 PHP
php自动加载方式集合
2016/04/04 PHP
Javascript的一种模块模式
2008/03/22 Javascript
javascript 跳转代码集合
2009/12/03 Javascript
Ext JS 4官方文档之三 -- 类体系概述与实践
2012/12/16 Javascript
Js数组的操作push,pop,shift,unshift等方法详细介绍
2012/12/28 Javascript
Jquery中$.post和$.ajax的用法小结
2015/04/28 Javascript
JSON与XML优缺点对比分析
2015/07/17 Javascript
javascript中$(function() {});写与不写有哪些区别
2015/08/10 Javascript
node.js中grunt和gulp的区别详解
2017/07/17 Javascript
Vue代码分割懒加载的实现方法
2017/11/23 Javascript
JS基于递归实现网页版计算器的方法分析
2017/12/20 Javascript
在Mac下彻底卸载node和npm的方法
2018/05/16 Javascript
解决vuejs 使用value in list 循环遍历数组出现警告的问题
2018/09/26 Javascript
在微信小程序中保存网络图片
2019/02/12 Javascript
JavaScript数据结构与算法之检索算法示例【二分查找法、计算重复次数】
2019/02/22 Javascript
解决一个微信号同时支持多个环境网页授权问题
2019/08/07 Javascript
javascript实现摄像头拍照预览
2019/09/30 Javascript
vue实现购物车选择功能
2020/01/10 Javascript
微信小程序实现购物车小功能
2020/12/30 Javascript
[13:18]《一刀刀一天》之DOTA全时刻21:详解TI新赛制 A队再露獠牙
2014/06/24 DOTA
使用Python编写简单的画图板程序的示例教程
2015/12/08 Python
Python cookbook(数据结构与算法)让字典保持有序的方法
2018/02/18 Python
Python饼状图的绘制实例
2019/01/15 Python
Python3并发写文件与Python对比
2019/11/20 Python
numpy.transpose()实现数组的转置例子
2019/12/02 Python
详解tensorflow之过拟合问题实战
2020/11/01 Python
利用python实现后端写网页(flask框架)
2021/02/28 Python
如何利用find命令查找文件
2015/02/07 面试题
经典广告词大全
2014/03/14 职场文书
群众路线党课主持词
2014/04/01 职场文书
走进敬老院活动总结
2014/07/10 职场文书
医生见习报告范文
2014/11/03 职场文书
2015年国际护士节演讲稿
2015/03/18 职场文书
MySQL主从搭建(多主一从)的实现思路与步骤
2021/05/13 MySQL
GTX1650super好不好 gtx1650super显卡属于什么级别
2022/04/08 数码科技