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

异步脚本加载

阻塞性脚本

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