摘要:但是在瀏覽器端,加載模塊需要向服務(wù)器發(fā)送請(qǐng)求,會(huì)受到網(wǎng)絡(luò)的影響。如果模塊的加載需要等很長時(shí)間,瀏覽器就會(huì)處于假死狀態(tài)。即,中文名為異步模塊定義。模塊中,中的回調(diào)函數(shù)會(huì)在中所有腳本執(zhí)行完畢并且其依賴的所有模塊都加載完畢后才會(huì)被調(diào)用。
1.模塊與模塊化開發(fā)
模塊:實(shí)現(xiàn)特定功能的一組方法
模塊化開發(fā):隨著瀏覽器性能的提升,相關(guān)技術(shù)的進(jìn)步,前端項(xiàng)目變得越來越復(fù)雜。為了提高開發(fā)效率,人們將特定功能的方法/代碼放在一起,構(gòu)成模塊,方便在開發(fā)過程中復(fù)用,但是出現(xiàn)了很多問題:全局變量的使用沖突,函數(shù)命名沖突,依賴關(guān)系管理困難。為了解決上述問題,制定了一些方法和規(guī)范來解決上述問題——CommonJS、AMD、CMD
2.CommonJSCommonJS是起源于服務(wù)器端模塊化開發(fā)的規(guī)范
定義模塊:一個(gè)多帶帶的文件就是一個(gè)模塊,每一個(gè)模塊都是一個(gè)多帶帶的作用域(在模塊內(nèi)部定義的變量,無法被其他模塊讀取,除非定義為global對(duì)象的屬性)
模塊輸出:模塊只有一個(gè)出口 module.exports 對(duì)象,需要將模塊希望輸出的內(nèi)容放在該對(duì)象中
加載模塊:加載模塊使用require方法,該方法讀取一個(gè)文件并執(zhí)行,返回文件內(nèi)部的 module.exports 對(duì)象
//模塊定義 myModel.js var name = "Byron"; function printName(){ console.log(name); } function printFullName(firstName){ console.log(firstName + name); } module.exports = { printName: printName, printFullName: printFullName }
//加載模塊 var nameModule = require("./myModel.js"); nameModule.printName(); // 在myModel模塊外部是無法獲取其內(nèi)部定義的變量name
問題:加載模塊和操作模塊提供的變量和方法是同步的,即操作模塊提供的變量和方法必須得等到加載模塊完成后才可以執(zhí)行。在服務(wù)器端,所有的模塊(js文件)都放在硬盤中,因此模塊的加載速度很快。但是在瀏覽器端,加載模塊需要向服務(wù)器發(fā)送請(qǐng)求,會(huì)受到網(wǎng)絡(luò)的影響。如果模塊的加載需要等很長時(shí)間,瀏覽器就會(huì)處于“假死”狀態(tài)。因此CommonJS只適用于服務(wù)器端,并不適用于瀏覽器端。
3.AMDAMD即 Asynchronous Module Definition,中文名為異步模塊定義。它是一個(gè)在瀏覽器端模塊化開發(fā)的規(guī)范
RequireJS是遵循AMD規(guī)范的一個(gè)JavaScript文件和模塊的加載器
requireJS主要解決兩個(gè)問題:
js文件之間的依賴關(guān)系:被依賴的文件需要早于依賴它的文件加載到瀏覽器
js加載的時(shí)候?yàn)g覽器會(huì)停止頁面渲染,加載文件越多,頁面失去響應(yīng)時(shí)間越長
使用定義模塊:requireJS定義了一個(gè)函數(shù) define,它是全局變量,用來定義模塊
define(id?, dependencies?, factory);
id:可選參數(shù),用來定義模塊的標(biāo)識(shí),如果沒有提供該參數(shù),默認(rèn)為該模塊對(duì)應(yīng)的腳本文件名(去掉拓展名)
dependencies:可選參數(shù),是一個(gè)當(dāng)前模塊依賴的模塊名稱數(shù)組
factory:必填參數(shù),模塊初始化要執(zhí)行的函數(shù)或?qū)ο?。如果為函?shù),它應(yīng)該只被執(zhí)行一次。如果是對(duì)象,此對(duì)象應(yīng)該為模塊的輸出值
加載和使用模塊:
require([module], callback);
1.[module],是一個(gè)數(shù)組,指定了要加載的模塊
2.callback,是加載成功之后的回調(diào)函數(shù)
例子:
require(["math"], function (math) { math.add(2, 3); }); console.log("hello world");
console.log()的執(zhí)行和模塊的加載執(zhí)行是異步的,當(dāng)模塊加載完畢,并且當(dāng)前頁面所有代碼執(zhí)行完畢后才會(huì)執(zhí)行回調(diào)函數(shù)。
測試// html
//main.js require(["sayName", "sayAge", "sayTime"], function(sayName, sayAge,sayTime){ alert("加載成功?。?) }) alert("hahaha") // sayName.js define(function(p){ alert("xin") }) // sayAge.js define(["jquery"],function($){ alert("22") }) // sayTime.js define(function(){ alert(Date.now()) })
結(jié)果:依次彈出:hahaha, xin, 1498193441948, 22, 加載成功!!
請(qǐng)求后的html文件
各種文件的加載順序
總結(jié):
通過上面的例子,可以看到RequireJS會(huì)動(dòng)態(tài)的創(chuàng)建異步腳本去加載各種依賴模塊,加載順序和聲明模塊時(shí)指定依賴模塊的順序有關(guān)。
腳本加載完畢后會(huì)立即執(zhí)行,并不能保證這些腳本執(zhí)行順序。
一個(gè)模塊依賴的所有模塊都加載完畢后,該模塊的回調(diào)函數(shù)才會(huì)被執(zhí)行。
main模塊中,require中的回調(diào)函數(shù)會(huì)在main中所有腳本執(zhí)行完畢并且其依賴的所有模塊都加載完畢后才會(huì)被調(diào)用。
4.CMDCMD即 Common Module Definition,中文為通用模塊定義,它是一個(gè)在瀏覽器端模塊化開發(fā)的規(guī)范
Sea.js是遵循AMD規(guī)范的一個(gè)JavaScript文件和模塊的加載器
Sea.js推薦一個(gè)模塊一個(gè)文件
使用定義模塊:SeaJS定義了一個(gè)函數(shù) define,它是全局變量,用來定義模塊
define(id?, dependencies?, factory); //例子 define(function(require, exports, module) { // 通過 require 引入依賴 var $ = require("jquery"); var Spinning = require("./spinning"); // 通過 exports 對(duì)外提供接口 exports.doSomething = ... // 或者通過 module.exports 提供整個(gè)接口 module.exports = ... });
id:可選(推薦不寫,默認(rèn)為文件名),用來定義模塊的標(biāo)識(shí),通常用文件名作為模塊id
dependencies:可選(推薦不寫),是一個(gè)當(dāng)前模塊依賴的模塊名稱數(shù)組(因?yàn)镃MD推崇依賴就近,因此一般不在此處指定)
factory:
function(require, exports, module)
require(id):require 是一個(gè)方法,接受模塊標(biāo)識(shí)作為唯一參數(shù),用來獲取其他模塊提供的接口
exports 是一個(gè)對(duì)象,用來向外提供模塊接口
module 是一個(gè)對(duì)象,上面存儲(chǔ)了與當(dāng)前模塊相關(guān)聯(lián)的一些屬性和方法
測試//html
// main.js define(function(require, exports, module) { alert("aaa") var sayName = require("sayName") sayName() var date = new Date() // 50s后再執(zhí)行require("sayAge") while(Date.now()-date<50000){} var sayAge = require("sayAge") sayAge() }); // sayName.js define(function(require, exports, module) { module.exports = function(){ alert("xin") } }); // sayAge.js define(function(require, exports, module) { module.exports = function(){ alert("22") } });
結(jié)果:依次彈出:aaa, xin ,(50秒后輸出)22
通過上面的時(shí)間圖可以看出,盡管在main.js中,var sayAge = require("sayAge")被延遲了(大約)50s才執(zhí)行,但是sayAge.js的加載卻沒有收到影響(sayAge.js在200多ms的時(shí)候就加載完畢了),只是sayAge的執(zhí)行被延遲了(大約)50s。
通過上述實(shí)驗(yàn)可以得到以下結(jié)論:seajs會(huì)分析依賴哪些模塊,然后加載這些模塊,加載完成后先不執(zhí)行,當(dāng)使用require語句的時(shí)候,才執(zhí)行對(duì)應(yīng)的模塊,模塊的執(zhí)行順序和書寫順序是完全一致的
AMD和CMD
模塊定義時(shí)對(duì)依賴的處理不同:
AMD推崇依賴前置,在定義模塊的時(shí)候就要聲明其依賴的模塊
CMD推崇就近依賴,只有在用到某個(gè)模塊的時(shí)候再去require
依賴模塊加載的過程以及依賴模塊執(zhí)行的時(shí)機(jī)不同:
AMD依賴前置,js可以方便知道依賴模塊是誰,立即加載并執(zhí)行,所有依賴模塊都加載執(zhí)行完后會(huì)進(jìn)入require的回調(diào)函數(shù),執(zhí)行主邏輯,這樣的效果就是依賴模塊的執(zhí)行順序和書寫順序不一定一致
CMD就近依賴,需要使用把模塊變?yōu)樽址馕鲆槐椴胖酪蕾嚵四切┠K,然后加載這些模塊,加載完成后先不執(zhí)行,當(dāng)使用require語句的時(shí)候,才執(zhí)行對(duì)應(yīng)的模塊,模塊的執(zhí)行順序和書寫順序是完全一致的
模塊的加載都是異步的
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/83605.html
摘要:開篇我叫王彬,現(xiàn)在是百度首頁業(yè)務(wù)部原網(wǎng)頁搜團(tuán)隊(duì)索部前端的實(shí)習(xí),兩天前我得知我所在的部門只有兩個(gè),而且要分給策略,這就意味著我要面臨千軍萬馬過獨(dú)木橋的秋招??偨Y(jié)我在百度實(shí)習(xí)時(shí)接觸到過一個(gè)框架,用于百度首頁和首頁的模塊化開發(fā)。 之一:關(guān)于Cmd和Amd 為什么想起來做這樣一個(gè)專題呢,答案應(yīng)該是為了勉勵(lì)面試筆試秋招中的自己吧!而且也是為了和我一樣的你。 1.開篇 我叫王彬,現(xiàn)在是百度首頁業(yè)務(wù)...
摘要:模塊標(biāo)準(zhǔn)有三個(gè)全局變量和。模塊中有兩種方式提供對(duì)外的接口,一種是,一種是使用進(jìn)行返回。規(guī)范中,函數(shù)同樣有一個(gè)公有屬性。由于和都可以使用來定義對(duì)外接口,故可以合并成一句代碼。 模塊標(biāo)準(zhǔn) CommonJS CommonJS 有三個(gè)全局變量 module、exports 和 require。但是由于 AMD 也有 require 這個(gè)全局變量,故不使用這個(gè)變量來進(jìn)行檢測。 如果想要對(duì)外提供接...
摘要:若不存在則模塊標(biāo)識(shí)應(yīng)該默認(rèn)定義為在加載器中被請(qǐng)求腳本的標(biāo)識(shí)。其中是一個(gè)數(shù)組,里面的成員就是要加載的模塊是模塊加載完成之后的回調(diào)函數(shù)。在加載與兩個(gè)模塊之后執(zhí)行回調(diào)函數(shù)實(shí)現(xiàn)具體過程。在判斷是否支持是否存在,存在則使用方式加載模塊。 我的github(PS:希望star): https://github.com/tonyzheng1... 今天由于項(xiàng)目中引入的echarts的文件太大,req...
摘要:模塊化編程首先,我想說說模塊化編程這個(gè)概念當(dāng)我不清楚這個(gè)概念的時(shí)候,其實(shí)說什么模塊化編程多好多好都是懵逼的而我一直不覺得有多好,其實(shí)也是因?yàn)槲覐拈_始寫,就一直都在模塊化編程啊我們寫一個(gè)文件然后我們?cè)谖募幸肴缓笳{(diào)用方法哈哈這樣已經(jīng)是模塊化 模塊化編程 首先,我想說說模塊化編程這個(gè)概念當(dāng)我不清楚這個(gè)概念的時(shí)候,其實(shí)說什么模塊化編程多好多好都是懵逼的而我一直不覺得有多好,其實(shí)也是因?yàn)槲覐?..
摘要:來源于阿賢博客模塊化今天給大家寫一篇關(guān)于前端模塊化開發(fā)知識(shí)點(diǎn)。前端模塊化開發(fā)那點(diǎn)歷史模塊化是指在解決某個(gè)復(fù)雜混雜問題時(shí),依照一種分類的思維把問題進(jìn)行系統(tǒng)性的分解以之處理。 來源于:阿賢博客 javascript模塊化 今天給大家寫一篇關(guān)于前端模塊化開發(fā)知識(shí)點(diǎn)。 前端模塊化開發(fā)那點(diǎn)歷史 模塊化: 是指在解決某個(gè)復(fù)雜、混雜問題時(shí),依照一種分類的思維把問題進(jìn)行系統(tǒng)性的分解以之處理。模塊...
閱讀 1200·2023-04-26 02:42
閱讀 1641·2021-11-12 10:36
閱讀 1804·2021-10-25 09:47
閱讀 1274·2021-08-18 10:22
閱讀 1815·2019-08-30 15:52
閱讀 1225·2019-08-30 10:54
閱讀 2642·2019-08-29 18:46
閱讀 3504·2019-08-26 18:27