浅谈js文件引用方式及其同步执行与异步执行

任何以appendChild(scriptNode) 的方式引入的js文件都是异步执行的 (scriptNode 需要插入document中,只创建节点和设置 src 是不会加载 js 文件的,这跟 img 的与加载不同 )

html文件中的<script>标签中的代码或src引用的js文件中的代码是同步加载和执行的

html文件中的<script>标签中的代码使用document.write()方式引入的js文件是异步执行的

html文件中的<script>标签src属性所引用的js文件的代码内再使用document.write()方式引入的js文件是同步执行的

1、

<script>
//同步加载执行的代码
</script>

2、

<script src="xx.js"></script> //同步加载执行xx.js中的代码

3、

<script>
document.write('<script src="xx.js"><\/script>');  //异步加载执行xx.js中的代码
</script>

4、

<script src="xx.js"></script>

xx.js中有下面代码:

document.write('<script src="11.js"><\/script>');
document.write('<script src="22.js"><\/script>');

则xx.js和11.js、22.js 都是同步加载和执行的。

如果 xx.js 以插入方式异步加载,则 11.js 和 22.js 仍然是同步加载的(异步中的同步,即,这2个文件的加载是分先后次序的)

测试:在11中 alert, 22中 document.write() ,可以看到 22中写入语句被阻塞

5、

下面这种方式,xx.js会在appendChild执行之后异步加载执行

var script = document.createElement("script");
script.setAttribute("src","xx.js");
documenrt.getElementsByTagName("head")[0].appendChild(script);

一个加载 js 文件的 函数:

var loadJS = function(url,callback){
var head = document.getElementsByTagName('head')[0],
script = document.createElement('script');
script.src = url;
script.type = "text/javascript";
head.appendChild( script);
  script.onload = script.onreadystatechange = function(){
//script 标签,IE 下有 onreadystatechange 事件, w3c 标准有 onload 事件
//这些 readyState 是针对IE8及以下的,W3C 标准因为script 标签没有这个 onreadystatechange 所以也不会有 this.readyState ,
// 好在文件加载不成功 onload 不会执行,(!this.readyState) 是针对 W3C标准的
if ((!this.readyState) || this.readyState == "complete" || this.readyState == "loaded" ){
 callback();
 }
 else
 {
 alert("can not load the js file")
 }
 }
 }

对于第4点的测试(其中插入 alert 很容易看到加载时阻塞的)

tryjs.html

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<script src="tryjs.js"
onload="if(!document.all){console.log('outer js callback, not IE');}"
onreadystatechange="console.log('outer js callback ',this.readyState,' IE');"></script>

<body>

</body>
</html>

tryjs.js

console.log('write begin');
document.write('<script src="try.1.js" onreadystatechange="console.log(\'file 1 callback \',this.readyState,\' IE\');" onload="if(!document.all){console.log(\'file 1 callback,NOT IE \');}"><\/script>');
document.write('<script src="try.2.js" onreadystatechange="console.log(\'file 2 callback \',this.readyState,\' IE\');" onload="if(!document.all){console.log(\'file 2 callback,NOT IE \');}"><\/script>');
console.log('write finished');

try.1.js

console.log('loadjs 1 begin');
console.log('loadjs 1 finished');

try.2.js

console.log('loadjs 2 begin');
console.log('loadjs 2 finished');

测试结果(file 2 和 file 1 的 callback complete 在IE7\8\9次序不确定)

IE 7:

日志: outer js callback loading IE
日志: outer js callback loaded IE
日志: write begin
日志: write finished
日志: outer js callback complete IE
日志: file 1 callback loading IE
日志: file 2 callback loading IE
日志: loadjs 1 begin
日志: loadjs 1 finished
日志: loadjs 2 begin
日志: loadjs 2 finished
日志: file 2 callback complete IE
日志: file 1 callback complete IE

IE8:

日志: outer js callback loading IE
日志: outer js callback loaded IE
日志: write begin
日志: write finished
日志: outer js callback complete IE
日志: file 1 callback loading IE
日志: file 2 callback loading IE
日志: loadjs 1 begin
日志: loadjs 1 finished
日志: loadjs 2 begin
日志: loadjs 2 finished
日志: file 2 callback complete IE
日志: file 1 callback complete IE

IE9:

日志: write begin
日志: write finished
日志: outer js callback complete IE
日志: file 1 callback loading IE
日志: file 2 callback loading IE
日志: loadjs 1 begin
日志: loadjs 1 finished
日志: loadjs 2 begin
日志: loadjs 2 finished
日志: file 1 callback complete IE
日志: file 2 callback complete IE

FIREFOX:

write begin
write finished
outer js callback, not IE
loadjs 1 begin
loadjs 1 finished
file 1 callback,NOT IE
loadjs 2 begin
loadjs 2 finished
file 2 callback,NOT IE

CHROME:

write begin
write finished
outer js callback, not IE
loadjs 1 begin
loadjs 1 finished
file 1 callback,NOT IE
loadjs 2 begin
loadjs 2 finished
file 2 callback,NOT IE

以上就是小编为大家带来的浅谈js文件引用方式及其同步执行与异步执行的全部内容了,希望对大家有所帮助,多多支持我们~

(0)

相关推荐

  • JS 动态加载js文件和css文件 同步/异步的两种简单方式

    /*动态添加js或css,URL:文件路径,FileType:文件类型(js/css)*/ function AddJsFiles(URL,FileType){ var oHead = document.getElementsByTagName('HEAD').item(0); var addheadfile; if(FileType=="js"){ addheadfile= document.createElement("script"); addheadfile

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

    对于JS文件的引用,尽管当前有不少框架和工具(比如webpack,commonjs,requiresjs等)都做了很好的处理.但是抛开这些框架,了解原生的加载方式还是不无裨益.本文简述一些js文件的同步和异步加载方式. 同步加载 可在html文件里以<script>标签插入,这是初学时最基本的方式. 准备两个js文件如下: calc1.js console.log('calc1 loading begin') function add(...args) { return args.reduce

  • 同步异步动态引入js文件的几种方法总结

    动态加载js文件 有时候我们需要根据参数不同来引入不同的js文件,用html直接写标签满足不了我们的需求,总结几种方法,以及同步异步加载的各种需求 一.直接加载 <div id="divId"></div> <script> 二.异步加载,并发执行,但引入js内容不能直接使用 //1.1 直接document.write document.write("<script src='test.js'><\/script>

  • javascript 文件的同步加载与异步加载实现原理

    HTML 4.01 的script属性 charset: 可选.指定src引入代码的字符集,大多数浏览器忽略该值. defer: boolean, 可选.延迟脚本执行,相当于将script标签放入页面body标签的底部,js脚本会在document的DOMContentLoaded之前执行.除IE和较新版本的Firefox外,其他浏览器并未支持. language: 已废弃.大部分浏览器会忽略该值. src: 可选.指定引入的外部代码文件,不限制后缀名. type: 必选.指定脚本的内容类型(M

  • 浅谈js文件引用方式及其同步执行与异步执行

    任何以appendChild(scriptNode) 的方式引入的js文件都是异步执行的 (scriptNode 需要插入document中,只创建节点和设置 src 是不会加载 js 文件的,这跟 img 的与加载不同 ) html文件中的<script>标签中的代码或src引用的js文件中的代码是同步加载和执行的 html文件中的<script>标签中的代码使用document.write()方式引入的js文件是异步执行的 html文件中的<script>标签src

  • 浅谈JS函数定义方式的区别

    关于JS的函数定义方式有以下两种: (1)典型的函数声明 function slide(arguments){ //...code } (2)以函数表达式的形式定义函数 var slide = function(arguments){ //...code } 虽然上面两种方式逻辑上是等价的,但是还是有点小区别: 区别一:例一中的函数会在代码执行以前被加载到作用域中,而例二则是在代码执行到那一行的时候才会有定 义: 区别二:函数声明会给函数指定一个名字,而函数表达式则是创建一个匿名函数,然后将这个

  • 浅谈js中的引用和复制(传值和传址)

    好像一般很少人讲到js中的引用和复制,不过弄清楚这个概念可以帮助理解很多东西 先讲一下很基础的东西,看看js中几种数据类型分别传的什么 引用:对象.数组.函数 复制:数字.布尔 字符串单独说明,因为它的特殊性,无法确定是传递引用还是复制数值(因为字符串的值是没法改变的,所以纠结这个问题也是没意义的)但是用于比较的时候显然是属于传值比较(稍后具体说比较的事) 下面讲一下在使用中的具体体现 最普通的使用就是赋值了 var a = 1; var b = a; //赋的是a的复制值 b ++; aler

  • 浅谈js函数三种定义方式 & 四种调用方式 & 调用顺序

    在Javascript定义一个函数一般有如下三种方式: 函数关键字(function)语句: function fnMethodName(x){alert(x);} 函数字面量(Function Literals): var fnMethodName = function(x){alert(x);} Function()构造函数: var fnMethodName = new Function('x','alert(x);') // 由Function构造函数的参数个数可变.最后一个参数写函数体

  • 浅谈js中的三种继承方式及其优缺点

    第一种,prototype的方式: //父类 function person(){ this.hair = 'black'; this.eye = 'black'; this.skin = 'yellow'; this.view = function(){ return this.hair + ',' + this.eye + ',' + this.skin; } } //子类 function man(){ this.feature = ['beard','strong']; } man.pr

  • 浅谈JS中的三种字符串连接方式及其性能比较

    工作中经常会碰到要把2个或多个字符串连接成一个字符串的问题,在JS中处理这类问题一般有三种方法,这里将它们一一列出顺便也对它们的性能做个具体的比较. 第一种方法 用连接符"+"把要连接的字符串连起来: str="a"; str+="b"; 毫无疑问,这种方法是最便捷快速的,如果只连接100个以下的字符串建议用这种方法最方便. 第二种方法 以数组作为中介用 join 连接字符串: var arr=new Array(); arr.push(a);

  • 浅谈js的ajax的异步和同步请求的问题

    先来看以下代码: var flag=true; var index=0; $.ajax({ url: "http://www.jb51.net/", success: function(data){ flag=false; } }); while(flag){ index++; } alert(index); 请问最后alert的index的结果是多少? 可能有人会说0呗.实际上却没那么简单.大家可以自己试试看.可以看到最终程序进入了一个死循环!怎么会这样呢! 我们在看一段代码: va

  • 浅谈JS前端模块化的几种规范

    前言 有这样一个场景,客户端运行很久,但是法务部和数据部需要收集用户的一些信息,这些信息收集好之后需要进行相应的数据处理,之后上报到服务端.客户端提供一个纯粹的js执行引擎,不需要 WebView 容器.iOS 端有成熟的JavaScriptCore.Android 可以使用 V8 引擎.这样一个引擎配套有一个 SDK,访问 Native 的基础能力和数据运算能力,可以看成是一个阉割版的 Hybrid SDK 额外增加了一些数据处理能力. 问题结束了吗?处理逻辑的时候还需要用到2个库:cheer

  • 浅谈JS的二进制家族

    概述 Blob: 前端的一个专门用于支持文件操作的二进制对象 ArrayBuffer:前端的一个通用的二进制缓冲区,类似数组,但在API和特性上却有诸多不同 Buffer:Node.js提供的一个二进制缓冲区,常用来处理I/O操作 Blob 我们首先来介绍Blob,Blob是用来支持文件操作的.简单的说:在JS中,有两个构造函数 File 和 Blob, 而File继承了所有Blob的属性. 所以在我们看来,File对象可以看作一种特殊的Blob对象. 在前端工程中,我们在哪些操作中可以获得Fi

  • 浅谈JS正则表达式的RegExp对象和括号的使用

    RegExp对象的创建: 常规的正则表达式的创建可用直接量,即斜杠 "/" 括起来的字符.但在要求参数变化的环境下,RegExp()构造函数是更好的选择: var reg1 = /'\w+'/g; var reg2 = new RegExp('\'\\w+\'','g'); 对比两种创建方式,RegExp中的第一个参数为要创建的正则字符串,一方面注意,因为不是直接量的表示形式,因此不用斜杠" / "括起来了:而是字符串中必须要对引号" ' "和转

随机推荐