深入理解JS异步编程五(脚本异步加载)

版权声明:本文为吴孔云博客原创文章,转载请注明出处并带上链接,谢谢。 https://blog.csdn.net/wkyseo/article/details/51582801

异步脚本加载

阻塞性脚本

JavaScript在浏览器中被解析和执行时具有阻塞的特性,也就是说,当JavaScript代码执行时,页面的解析、渲染以及其他资源的下载都要停下来等待脚本执行完毕

浏览器是按照从上到下的顺序解析页面,因此正常情况下,JavaScript脚本的执行顺序也是从上到下的,即页面上先出现的代码或先被引入的代码总是被先执行,即使是允许并行下载JavaScript文件时也是如此。注意我们这里标红了”正常情况下”,原因是什么呢?我们知道,在HTML中加入JavaScript代码有多种方式,概括如下(不考虑require.js或sea.js等模块加载器):

(1)正常引入:即在页面中通过<script>标签引入脚本代码或者引入外部脚本 (2)通过document.write方法向页面写入<script>标签或代码 (3)通过动态脚本技术,即利用DOM接口创建<script>元素,并设置元素的src,然后再将元素添加进DOM中。 (4)通过Ajax获取脚本内容,然后再创建<script>元素,并设置元素的text,再将元素添加进DOM中。 (5)直接把JavaScript代码写在元素的事件处理程序中或直接作为URL的主体

具体参考 http://www.jb51.net/article/77920.htm

脚本延迟运行

一般在JS页面延迟执行一些方法。可以使用以下的方法:

Window.setTimeout  

jQuery.delay

jQuery.queue和jQuery.dequeue
<script src="deferdemo.js" defer></script>

加上 defer 等于在页面完全在入后再执行,相当于 window.onload ,但应用上比 window.onload 更灵活!

<script type="text/javascript" src="demo_async.js" async="async"></script>

使用async属性,浏览器会下载js文件,同时继续对后面的内容进行渲染 通常如果js不需要改变DOM结构时可以使用async进行异步加载(比如一些统计代码可以异步加载,因为此代码与页面执行逻辑无关,不会改变DOM结构)

SeaJS与RequireJS

网上写amd和cmd的文章很多,当然也有很多都是误人子弟的片面的看法,所以还是推荐自己看官方文档多加尝试去理解。

“RequireJS 遵循的是 AMD(异步模块定义)规范,SeaJS 遵循的是 CMD (通用模块定义)规范”。

AMD 是 RequireJS 在推广过程中对模块定义的规范化产出。 CMD 是 SeaJS 在推广过程中对模块定义的规范化产出。

amd 规划 https://github.com/amdjs/amdjs-api/wiki/AMD-(%E4%B8%AD%E6%96%87%E7%89%88)

cmd 规范 https://github.com/seajs/seajs/issues/242

区别:

  1. 对于依赖的模块,AMD 是提前执行,CMD 是延迟执行。不过 RequireJS 从 2.0 开始,也改成可以延迟执行(根据写法不同,处理方式不同)
  2. CMD 推崇依赖就近,AMD 推崇依赖前置。

ECMAScript6 Moudle

历史上,JavaScript一直没有模块(module)体系,无法将一个大程序拆分成互相依赖的小文件,再用简单的方法拼装起来。其他语言都有这项功能,比如Ruby的require、Python的import,甚至就连CSS都有@import 到了ES6,实现了模块化的功能,功能上基本可以取代 cmd和amd的规范,

模块的功能主要由两个命令构成,export和import,export命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能。

export的写法,

// profile.js
var firstName = 'Michael';
var lastName = 'Jackson';
var year = 1958;

export {firstName, lastName, year};

上面代码在export命令后面,使用大括号指定所要输出的一组变量。

import写法:

// main.js

import {firstName, lastName, year} from './profile';

function setName(element) {
  element.textContent = firstName + ' ' + lastName;
}

ES6模块加载的实质

ES6模块加载的机制,与CommonJS模块完全不同。CommonJS模块输出的是一个值的拷贝,而ES6模块输出的是值的引用。CommonJS模块输出的是被输出值的拷贝,也就是说,一旦输出一个值,模块内部的变化就影响不到这个值

ES6模块的运行机制与CommonJS不一样,它遇到模块加载命令import时,不会去执行模块,而是只生成一个动态的只读引用。等到真的需要用到时,再到模块里面去取值,换句话说,ES6的输入有点像Unix系统的”符号连接“,原始值变了,import输入的值也会跟着变。因此,ES6模块是动态引用,并且不会缓存值,模块里面的变量绑定其所在的模块。

// mod.js
function C() {
  this.sum = 0;
  this.add = function () {
    this.sum = 1;
  };
  this.show = function () {
    console.log(this.sum);
  }
}

export let c = new C();

上面的脚本mod.js,输出的是一个C的实例。不同的脚本加载这个模块,得到的都是同一个实例

// x.js
import {c} from './mod';
c.add();

// y.js
import {c} from './mod';
c.show();

// main.js
import './x';
import './y';

现在执行main.js,输出的是1。 证明加载的是同一个实例 参考 http://es6.ruanyifeng.com/#docs/module

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏诸葛青云的专栏

两个小巧好用的C语言编辑器

近期有一些新关注的伙伴在后台经常留言刚入门 C语言 我该选择什么 C语言 编辑器好呢?都说欲善其事必先利其器,网络上也有很多不同类型的编辑器,让人很难进行抉择!...

61700
来自专栏诸葛青云的专栏

c语言:输入任意10个正整数,按照升序排序输出:(冒泡算法)

其实学编程关键是学习其思想,如果你精通了一门,再去学其他的时候也很容易上手。C不会过时的,尤其是在unix、linux操作平台上,学好C是必须的。

3.1K00
来自专栏程序员的知识天地

零基础却想做一个程序员,到底如何学习呢?

众所周知程序员是21世纪比较吃香的工作。程序员工资高还不需要和复杂的社会打交道。那么作为一个零基础,什么都不懂的人该怎么成为一名程序员?当程序员需要学什么?下面...

42210
来自专栏java一日一条

我的编码习惯 - 配置规范(导读)

工作中少不了要制定各种各样的配置文件,这里和大家分享一下工作中我是如何制定配置文件的,这是个人习惯,在我在的项目组中目前要定义配置文件都安装这个步骤,效果还不错...

10620
来自专栏诸葛青云的专栏

老司机学习C语言的一些心的经验!

C语言是一种计算机程序设计语言。它既有高级语言的特点,又具有汇编语言的特点。它可以作为系统设计语言,编写工作系统应用程序,也可以作为应用程序设计语言,编写不依赖...

9400
来自专栏诸葛青云的专栏

C语言中你必须知道的几大排序算法

在实际使用数组的过程中,数组不仅可以存储多个同类型的数据,而且要求这些数据按照某种特征进行排序。例如,学生的成绩,需要按照从高到低的顺序排列,这就需要使用排序算...

13700
来自专栏云飞学编程

看大牛用Python实现发送知乎私信功能

学习知识点: - 面向对象编程 - 读写文件操作 - 网络请求的方式 - 实现发送私信的功能 - 可以实现批量发送私信的目的 推荐下小编的Python学习群...

27720
来自专栏程序员的知识天地

闭包使用的3种情景

定义:通俗讲,闭包是函数里面再定义一个函数,里层函数能访问到外层函数的布局变量,也就是说闭包是一个能访问外层函数布局变量的函数。常用情景有以下3种。

50410
来自专栏诸葛青云的专栏

人生苦短,我用Python

据 IEEE Spectrum 发布的研究报告显示,2017年,Python成为最受欢迎的编程语言,而2016年,Python也是高居第三,可见Python受众...

6700
来自专栏用户2442861的专栏

awk工作常用技巧

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/haluoluo211/article/d...

12320

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励