动态加载js如何保证顺序执行?

动态加载JS脚本,如何保证加载顺序 http://echizen.github.io/tech/2017/04-22-script-exec 阅读详情

我们知道,可以使用创建script标签的方法来动态加载js文件。

但随之带来问题,如果创建多个script标签来加载多个js文件,这些文件是异步并行加载的,默认添加了async属性,最后执行顺序不能保证是当初的scrpit标签创建顺序。

也就是说,如果我们引入的js之间有依赖关系,能不能加载成功不报错 就是个随机事件了~

function createScript (src) {
    let script = document.createElement('script');
    script.src = src;
    document.body.appendChild(script);
};

createScript('a.js');
createScript('b.js'); 
// 假定b.js依赖a.js的文件内容,因为网络等原因可能b.js会在a.js之前加载完,导致报错

因此上面的代码需要改进一下,通过监听onload 和 onreadystatechange,确保a.js全部执行完成后,才能加载b.js。

参考http://www.w3help.org/zh-cn/causes/BX9013

// 方法一:
function createScript(url, success) {
  let script = document.createElement('script');
  script.src = url;
  success = success || function(){};
  script.onload = script.onreadystatechange = function() {
    // onreadystatechange和readyState针对ie
    if (!this.readyState || this.readyState === 'loaded' || this.readyState === 'complete') {
      success();
      this.onload = this.onreadystatechange = null;
      this.parentNode.removeChild(this);
    }
  }
  document.body.appendChild(script);
}
//顺序执行加载外部 JS 文件
createScript('a.js',function (){
   createScript('b.js',function (){
      alert('ok');
   });
});

到这里就实现了动态加载js也能按顺序执行的效果。

然而这个解决方法实在是太长,所以找到了另一种简单粗暴的方法。

一开始script标签中的async属性不管是设置为true or false,都会在下载该js脚本的同时,不阻塞页面其他操作,且下载完会立即执行。

在Kyle Simpson的提议下,动态插入的script标签默认设置了属性async=true,以期异步执行。同时也可以设置async=false来保持插入顺序执行。(并行加载,顺序执行)

The proposal basically preserves Webkit (and IE)'s current default behavior, but in a more formalized and flexible way, which is that any script inserted dynamically will essentially default to behaving like a parser-inserted script with `async=true`.
该提议基本上保留了Webkit(和IE)的当前默认行为,但是以一种更加形式化和灵活的方式,即,动态插入的任何脚本本质上都将默认表现为具有async = true的解析器插入脚本。

The requested extension is that a dynamically inserted script tag which has `async=false` set on it will go into a separate loading "queue" of sorts, in that all such scripts with `async=false` will load in parallel but will execute in insertion order.
要求的扩展是动态插入的脚本标签上设置了async = false,它将进入单独的各种加载“队列”,因为所有带有async = false的脚本都将并行加载但将执行按照插入顺序。

所以我们只需要加上 "async=false" :

// 方法二:
function createScript (src) {
    let script = document.createElement('script');
    script.src = src;
    // 保证JS顺序执行!
    script.async = false
    document.body.appendChild(script);
};

createScript('a.js');
createScript('b.js'); 

       一行代码解决问题,完美😼

       这里延伸一下,外部引入脚本的script标签可以有defer和async属性,讲道理他们应该是这样的:

  1. defer属性:并行加载,文档全部解析完成后(DOMContentLoaded 事件触发之前),顺序执行。<script defer src="index.js"></script>
  2. async属性:并行加载,加载完立即执行,无序。<script async src="index.js"></script>
  3. 如果都没有,就会阻塞进程,加载执行完再继续往下解析文档。<script src="index.js"></script>

       所以理论上,如果在createScript里加入script.defer也可以保证顺序执行。但实际上试了却发现顺序也不能确定。在JavaScript高级程序设计(第3版)中有这么一句:

在现实当中,延迟脚本不一定按顺序执行,也不一定会在DOMContentLoaded 事件触发前执行,因此最好只包含一个延迟脚本。

 所以还是“async = false”大法好👌

毕设分享|基于16单片机的指纹识别电子密码锁设计 我们今天的工作生活中,很多的场合都需要身份的认证,而传统的基于标志的身份认证技术由于受到证件伪造以及密码破解等手段的威胁,逐渐表现得有些力不从心。怎样保护自己的重要文件资料,如何保证自己的隐私不被泄露?在传统的身份认证中,我们往往使用密码加密法,但是这种方法只是"防君子不防小人"。在高明的黑客眼里,由几个字符组成的密码脆弱得不堪一击。现在,科技的发展让我们有了新的选择——生物识别技术。将生物识别技术应用于笔记本、门锁等方面,可以对文件、财产起保护作用,并且可以进行身份识别。 阅读详情

相关推荐

QMT vs Ptrade:量化交易新手如何根据需求选择券商系统(附实战案例)

本文对比了QMT和Ptrade两大券商量化交易系统的核心差异,帮助量化交易新手根据需求选择合适的平台。QMT适合技术面策略开发,执行效率高;Ptrade则提供全面的财务数据和复杂策略支持。通过实战案例,展示了如何结合两平台优势实现高效量化交易。

weixin_42683394的博客 527

Vue中js 后边的代码比前边的先执行

Vue中js 后边的代码比前边的先执行 最近在项目中遇到了一个比较怪的js问题, 先看下出问题的代码: beforeUploadFunc(file) { let size = file.size / 1024 / 1024; if (size > 1) { this.$message.warning('不超过500kb') return; } getStsToken().then(response => { // 同步等待ossConf初始化 const stsCredent

CaptainCats的博客 1928

[捷稀 JCG Q30 Pro 刷机说明] 以刷入openwrt24.10为例

摘要: 本文详细介绍了捷稀JCG Q30 Pro路由器刷入OpenWrt 24.10系统的步骤。通过先刷入OpenWrt 23.05过渡固件,再升级Uboot,最后通过TFTP加载工厂镜像完成刷机。关键步骤包括解锁分区、刷写Uboot、进入恢复模式及配置网络。文章还提供了无线设置、Tailscale内网穿透等进阶命令,并附参考文档和固件下载链接。适用于有一定技术基础的玩家,需注意操作风险,严格按流程执行。

贤时间 7144

vue3异步加载js文件

vue3异步加载js文件

吃瓜群众的博客 2267

深入探究贝叶斯网络(Bayesian Network):从基础原理到实际应用

贝叶斯网络,也称为信念网络或有向无环图模型,是一种概率图模型。它使用有向无环图(DAG)来表示随机变量之间的条件依赖关系。每个节点代表一个随机变量,边表示变量之间的条件依赖关系。贝叶斯网络作为一种强大的工具,通过结合概率论和图论,为复杂系统建模和推理提供了有效手段。无论是在医学诊断、故障检测还是自然语言处理等领域,它都展示了巨大的潜力。然而,其计算复杂度高、结构学习困难等挑战也需要我们在实际应用中不断优化算法和技术。希望通过本文,你能对贝叶斯网络有更深入的理解,并能够在实际项目中灵活应用这一强大工具。

qq_28791753的博客 5973

硬件开发流程

研发流程在一个有一定规模的企业中起到了非常重要的作用,也是一个产品或者项目成功量产出货依赖的平台体系,作为工程师如果想要走的更远,就必须了解流程体系,了解如何对产品的开发质量进行更好的管控。...

weixin_44126796的博客 8382

script标签的同步异步加载

script标签默认是同步加载的,也就是说,当读到script标签是引入外部js文件的,会立即停止对页面的向下解析,然后下载脚本并且执行,如果说js文件相对来说比较大,而且网速什么的又不是很好,那么用户在浏览网页的时候,会有很长一段时间的等待,用户体验很差。 当js文件里面没有对DOM进行操作或者对css进行操作的时候,我们可以将这个js文件设置成异步加载的,这样子会让用户体验更好。 那么如何设置js文件的异步加载呢? 有两种方式: <script defer> <script

xiaozhang_jiuke的博客 4225

保姆级教程:用Qlib和LightGBM从零搭建你的第一个AI量化选股策略(附完整代码)

本文提供了一份详细的教程,教你如何使用Qlib和LightGBM从零搭建AI量化选股策略。教程涵盖了环境配置、数据获取、特征工程、模型训练和策略回测等关键步骤,并附有完整代码和常见问题解决方案,适合量化投资初学者快速上手。

weixin_29191081的博客 446

详解js异步加载的三种方式

详解js异步加载的三种方式 一.同步加载 默认正常模式下,JS是同步加载的,及优先加载JS,只有当JS文件下载完,dom和css才开始加载 同步加载是我们使用最多的一种方式,同步模式,又称为阻塞模式,会阻止浏览器的后续处理,停止后续的解析,要等js加载完并执行之后才能执行下一步,所以默认同步执行是最安全的。但这样如果js中有输出document内容、修改dom、重定向等行为,就会造成页面堵塞。所以一般建议把缺点:过多js加载会影响页面效率,一旦网速不好,那么整个网站将等待js加载而不进行后续渲染等工作。 &

V8min的博客 5989

YOLOv11 模型改进全流程:从代码修改到性能跃升,让你打造专属检测利器

无论是科研中需要发表创新点满满的论文,还是企业里要解决特定场景的检测难题,这套方法都能让你在YOLOv11的基础上打造出“量身定制”的检测模型。别再让通用模型的“平庸性能”限制你的项目上限——现在就动手修改代码,让你的YOLOv11模型在精度、速度或小样本适应能力上实现跨越式提升,用技术突破证明你的AI研发实力!本文将带你从代码层面入手,完成从骨干网络到损失函数的全维度改进,真正掌握让YOLOv11“为你所用”的技术实力。该改进对小样本类别(如数据集中仅占5%的“稀有缺陷”)的识别精度提升显著。

m0_71589036的博客 402

YOLOv8改进 | 独家创新篇 | 给YOLOv8增加辅助可逆分支结构(PGI,1:1改进)(全网独家创新,附视频讲解)

这张图(图3)展示了可编程梯度信息(PGI)及其相关网络架构和方法。这种网络结构主要用于改进特征融合,以提高目标检测的性能。然而,由于信息瓶颈的存在,网络中可能会丢失一些信息。这是一种旨在减少信息丢失的网络设计。它通过可逆的列结构来尝试维持信息流通不受损失,但如图中“Heavy Cost”所示,这种结构会增加计算成本。c) 深度监督:这种方法通过在网络的多个层次中插入额外的监督信号来提高学习的效率和最终模型的性能。图中显示了通过深度监督连接的各个层。

Snu77的博客 3745

JavaScript异步加载,解决js阻塞

1.defer: 在script标签里添加defer,用于外部链接js文件,也可以异步加载内部脚本,会等待dom树生成后再执行js脚本代码 <script src="01.js" defer ></script> 2.async: 只能异步加载外部的链接文件,不能加载内部脚本,并且js文件加载完成后立即执行 <script src="01.js" async></script> 3.按需加载: 节省资源:在需要用到的时候再去引入,不需要用的

m0_58510118的博客 2028

uniapp(全端兼容) - 最新详细实现接入腾讯视频播放器功能插件,uniapp全平台端(小程序/H5网页/App/nvu)调用引入并使用腾讯视频播放组件完整全流程(详细示例源码,一键复制开箱即用)

uniapp腾讯视频,uniapp微信小程序腾讯视频,uniapp小程序接入腾讯视频详细示例教程源码,uniapp怎么在微信小程序平台使用腾讯视频插件,在uni-app中使用腾讯视频插件播放视频,uniapp调用腾讯视频,uniapp引入腾讯视频插件,uniapp小程序中引入腾讯视频无法播放,uniapp微信小程序平台引入腾讯视频播放不了黑屏,在uniapp开发的微信小程序中使用腾讯视频,uniapp如何引入腾讯视频插件播放视频,uni-app小程序平台引入腾讯视频插件播放腾讯视频,uniapp 小程序接入

✅ 精选推荐文章 1万+

关于js延迟加载的几种方法

1.defer 用途:表明脚本在执行时不会影响页面的构造。也就是说,脚本会被延迟到整个页面都解析完毕之后再执行。 <!DOCTYPE html> <html> <head> //浏览器会立即下载,但延迟执行。 <script src="defer1.js" defer="defer"></script> </head> <body> <!-- 这里放内容 --> </body> &

gercke的博客 1907

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

js学习1(入门篇)

js学习入门篇,语言定位,规范,使用方式安全

m0_60633107的博客 411

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

【小白鲨笔记】js面试题(一)

js面试题系列

小白鲨c宇宙的成长博客 159

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

DOM网页脚本动态顺序加载

介绍   最近为了提升页面加载速度,寻找了一下解决方案,其中方案之一就是让页面脚本动态顺序加载,以下介绍该方案的原理以及实现。   众所周知,浏览器加载 JavaScript 脚本,主要通过<script>元素完成。正常的网页加载流程是这样的。浏览器加载网页的流程一般如下: 浏览器一边下载 HTML 网页,一边开始解析。也就是说,不等到下载完,就开始解析。 解析过程中,浏览器发现  加载外部脚本时,浏览器会暂停页面渲染,等待脚本下载并执行完成后,再继续渲染。原因是 JavaScript 代码可

蓑笠翁 708

拜读阮一峰JavaScript教程笔记续

。。。中间写的全没了,后面再补   防止脚本阻塞: 1.defer属性,遇到script脚本,继续解析html,同时下载,即使这是下载完,也要等html解析完在执行代码,下载的代码不能有document.write(),可以保证js的顺序,对于内嵌脚本和动态生成的script脚本无效 2.async属性,遇到脚本,继续解析html,同时下载,这是脚本下载完,马上执行脚本,执行完脚本在继续解

weiyangxiaoping的博客 1116

面试:js 延迟加载方式

js 延迟加载方式

前端金牌摸鱼达人 4万+

180420 异步加载JavaScript

部分转自韩子迟,原文地址 js时间线 1、创建Document对象,开始解析web页面。解析HTML元素和他们的文本内容后添加Element对象和Text节点到文档中。这个阶段document.readyState = ‘loading’。 2、遇到link外部css,创建线程加载,并继续解析文档。 3、遇到script外部js,并且没有设置async、defer,浏览器加载,并阻塞,...

simpleone_的博客 244

【javascript】defer、async脚本特性

脚本会“在后台”下载,然后等 DOM 构建完成后,脚本才会执行。因此,请记得添加一个“正在加载”的提示,并禁用尚不可用的按钮。因此,在上面的示例中,两个脚本是并行下载的。当我们需要先加载 JavaScript 库,然后再加载依赖于它的脚本时,这可能会很有用。脚本就是一个会在加载完成时执行的完全独立的脚本。用于需要整个 DOM 的脚本,和/或脚本的相对执行顺序很重要的时候。一样,如果我们要加载一个库和一个依赖于它的脚本,那么顺序就很重要。用于独立脚本,例如计数器或广告,这些脚本的相对执行顺序无关紧要。

Jerryqjr的博客 999

HTML中的JavaScript

《JavaScript高级程序设计(第四版)》p13-p15 1. 标签位置 如果把所有JavaScript文件都放在<head>里,也就意味着必须把所有JavaScript代码都下载、解析和解释完成后,才能开始渲染页面(页面在浏览器解析到<body>的起始标签时开始渲染)。对于需要很多JavaScript的页面,这会导致页面渲染的明显延迟,在此期间浏览器窗口完全空白。为解决这个问题,现代web应用程序通常将所有JavaScript引用放在<body>元素中的页面内容

qq_38517015的博客 183

JS异步加载的三种方式

JS异步加载的三种方式 我们平时使用的最多的一种方式即同步加载,又称阻塞模式。会阻止浏览器的后续运行,停止后续的解析,只有当前加载完成后,才能进行下一步操作。所以接下来我会介绍三种异步加载的方式。 异步加载即非阻塞加载,浏览器在下载执行js的同时,还会继续进行后续页面的处理。 一、defer (IE适用) 代码块可以写在script标签中 <script src="test.js" defer></script> 或 <script src="test.js" defer&

weixin_45662100的博客 559

请说出 JavaScript无阻塞加载的具体方式?

在JavaScript中,无阻塞(非阻塞)加载是一种技术,它允许浏览器在加载和执行JavaScript代码的同时,继续加载和渲染页面的其他部分。这种方式的优点是,延迟脚本会按照在HTML文档中出现的顺序执行,所以可以处理脚本之间的依赖关系。你可以使用Ajax(或Fetch API)异步地加载脚本,然后在加载完成后使用。属性,这样浏览器会并行加载和执行脚本,而不会阻止HTML的解析。标签,这样脚本会在加载完成后立即执行,而不会阻止HTML的解析。这种方式的优点是,你可以控制何时开始加载和执行脚本。

csdn_Levy的博客 409

页面动态顺序加载第三方依赖

页面动态顺序加载第三方依赖。

weixin_41492957的博客 243

LABjs分析

  作者: oldj | 链接:http://oldj.net/article/labjs-study/  随着网页越做越复杂,页面上要用到的 JavaScript 也越来越多,一次性把所有可能会用到的 js 全包含在页面中显然不是一个好主意,于是各种各样动态按需加载 js 的方法逐渐流行起来,LABjs 就是这样一个有趣的项目,目前,包括 twitter 在内的很多网站都是 LABjs 的用户...

weixin_30785593的博客 298
下一篇: 赋值、浅拷贝和深拷贝的区别
evalost
博客等级 码龄9年 6粉丝 16原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值