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

发布时间 - 2026-01-11 02:52:20    点击率:

对于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里的调试结果如下:

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

通过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里的调试结果有时候能正确的输出如下:

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

那么我们就得需要解决加载顺序问题,保证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>

也能正确的输出结果。

总结

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

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

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


# 异步加载js文件  # js  # 同步异步加载  # js同步加载和异步加载  # JS异步加载的三种实现方式  # 详解JS异步加载的三种方式  # 浅析JS异步加载进度条  # JavaScript 脚本异步加载的几种实现方法  # 加载  # 多个  # 不无裨益  # 这是  # 很好  # 完成后  # 就能  # 也能  # 两种  # 可在  # 就得  # 很长  # 报错  # 再加  # 都做  # 也做  # 请参考  # 大家多多  # 正确地  # 文件合并 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 如何选择PHP开源工具快速搭建网站?  三星、SK海力士获美批准:可向中国出口芯片制造设备  什么是javascript作用域_全局和局部作用域有什么区别?  如何挑选高效建站主机与优质域名?  Python进程池调度策略_任务分发说明【指导】  Laravel如何自定义分页视图?(Pagination示例)  Zeus浏览器网页版官网入口 宙斯浏览器官网在线通道  详解ASP.NET 生成二维码实例(采用ThoughtWorks.QRCode和QrCode.Net两种方式)  Java遍历集合的三种方式  如何在万网自助建站平台快速创建网站?  ChatGPT 4.0官网入口地址 ChatGPT在线体验官网  Laravel怎么实现微信登录_Laravel Socialite第三方登录集成  使用C语言编写圣诞表白程序  Laravel观察者模式如何使用_Laravel Model Observer配置  Laravel全局作用域是什么_Laravel Eloquent Global Scopes应用指南  Laravel怎么发送邮件_Laravel Mail类SMTP配置教程  Chrome浏览器标签页分组怎么用_谷歌浏览器整理标签页技巧【效率】  轻松掌握MySQL函数中的last_insert_id()  Laravel怎么处理异常_Laravel自定义异常处理与错误页面教程  Windows11怎样设置电源计划_Windows11电源计划调整攻略【指南】  Laravel怎么做数据加密_Laravel内置Crypt门面的加密与解密功能  想要更高端的建设网站,这些原则一定要坚持!  Android滚轮选择时间控件使用详解  mc皮肤壁纸制作器,苹果平板怎么设置自己想要的壁纸我的世界?  如何用VPS主机快速搭建个人网站?  Laravel如何配置.env文件管理环境变量_Laravel环境变量使用与安全管理  php中::能调用final静态方法吗_final修饰静态方法调用规则【解答】  laravel怎么为API路由添加签名中间件保护_laravel API路由签名中间件保护方法  进行网站优化必须要坚持的四大原则  Laravel怎么多语言本地化设置_Laravel语言包翻译与Locale动态切换【手册】  Firefox Developer Edition开发者版本入口  齐河建站公司:营销型网站建设与SEO优化双核驱动策略  如何在万网利用已有域名快速建站?  奇安信“盘古石”团队突破 iOS 26.1 提权  Laravel如何处理文件下载请求?(Response示例)  Laravel如何实现用户角色和权限系统_Laravel角色权限管理机制  EditPlus中的正则表达式实战(5)  如何在 Go 中优雅地映射具有动态字段的 JSON 对象到结构体  Laravel怎么使用Intervention Image库处理图片上传和缩放  如何用PHP快速搭建CMS系统?  Laravel模型关联查询教程_Laravel Eloquent一对多关联写法  如何在建站宝盒中设置产品搜索功能?  如何实现建站之星域名转发设置?  在线制作视频网站免费,都有哪些好的动漫网站?  Laravel如何创建自定义中间件?(Middleware代码示例)  Laravel如何将应用部署到生产服务器_Laravel生产环境部署流程  如何用AI帮你把自己的生活经历写成一个有趣的故事?  Laravel怎么实现API接口鉴权_Laravel Sanctum令牌生成与请求验证【教程】  Win11怎么关闭资讯和兴趣_Windows11任务栏设置隐藏小组件  Swift中swift中的switch 语句