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