seajs模塊加載機(jī)制

本文談?wù)摰拇a版本是Sea.js 2.3.0替饿,seajs最新的版本是3.0,3.0版本變動(dòng)較大.

新事物的出現(xiàn)或多或少的是想改變已有的行為方式贸典,解決遇到的問(wèn)題视卢。關(guān)于這段歷史,大家可以看看這幾篇文章:why-seajs1廊驼、why-seajs2

關(guān)于seajs原理介紹和分析的文字也有不少据过,例如:Sea.js是如何工作的?妒挎、實(shí)例解析 SeaJS 內(nèi)部執(zhí)行過(guò)程 - 從 use 說(shuō)起绳锅、也有人分析了seajs代碼中的數(shù)據(jù)結(jié)構(gòu):SeaJSV1.1.0-代碼結(jié)構(gòu)和數(shù)據(jù)結(jié)構(gòu)


既然已經(jīng)有很多優(yōu)秀的文章介紹seajs了,為什么你還要浪費(fèi)時(shí)間呢酝掩?

因?yàn)槟X子不好使鳞芙,寫(xiě)作的過(guò)程使我審視自己的結(jié)論,加深了我對(duì)事物的理解期虾。

seajs干嘛的

SeaJS是一個(gè)遵循CMD規(guī)范的JavaScript模塊加載框架原朝,用以實(shí)現(xiàn)JavaScript的模塊化開(kāi)發(fā)及加載機(jī)制

注意關(guān)鍵詞:CommonJS規(guī)范,模塊加載镶苞,模塊化開(kāi)發(fā)

  • CMD規(guī)范全稱(chēng)Common Module Definition喳坠,該規(guī)范明確了模塊的基本書(shū)寫(xiě)格式和基本交互規(guī)則,即定義了一組模塊化開(kāi)發(fā)的接口宾尚,具體細(xì)節(jié)可以參看:CMD 模塊定義規(guī)范丙笋、英文 Common Module Definition

  • 有C++,Java煌贴,Python開(kāi)發(fā)經(jīng)驗(yàn)的同學(xué)應(yīng)該很容易理解模塊化開(kāi)發(fā)和模塊加載的概念御板,以java為例,類(lèi)是java的最小開(kāi)發(fā)單位牛郑,一個(gè)類(lèi)可以看做是一個(gè)最小模塊怠肋,一個(gè)或多個(gè)類(lèi)可以組成一個(gè)package,這種組織代碼的方式就是模塊化開(kāi)發(fā)

  • 當(dāng)我們?cè)谝粋€(gè)類(lèi)中import另一個(gè)package的內(nèi)容時(shí)淹朋,import的內(nèi)容最終會(huì)被包含進(jìn)當(dāng)前類(lèi)中笙各,seajs要做的一個(gè)事情就是模擬java中import這種模塊加載機(jī)制。

  • 與服務(wù)器端不同础芍,在瀏覽器端實(shí)現(xiàn)模塊加載又有其特點(diǎn):模塊(js文件)需要經(jīng)過(guò)網(wǎng)絡(luò)傳輸?shù)竭_(dá)用戶(hù)瀏覽器杈抢,那么何時(shí)將js文件下載到用戶(hù)本地?性能考慮仑性,提前將用到的js文件下載到用戶(hù)本地是首選惶楼,免去了執(zhí)行期從服務(wù)器請(qǐng)求文件消耗的時(shí)間,但同時(shí)seajs也提供了異步加載模塊的功能诊杆。

兩個(gè)核心

1. 模塊的依賴(lài)加載

如何從服務(wù)器獲取js文件歼捐,這里就不詳細(xì)解釋了,原理就是append script標(biāo)簽的方式晨汹。

模塊間的關(guān)系無(wú)非就是依賴(lài)和被依賴(lài)的關(guān)系豹储,具體到兩個(gè)模塊上,有下圖三種關(guān)系:

  1. a模塊依賴(lài)b模塊
  2. b模塊依賴(lài)a模塊
  3. a淘这,b模塊相互依賴(lài)
兩個(gè)模塊間的依賴(lài)關(guān)系

前兩種情況很好理解剥扣,對(duì)于第三種情況,seajs在3.0版本前是不支持循環(huán)依賴(lài)的慨灭,具體表現(xiàn)為模塊加載會(huì)中斷朦乏,a.doSomething()并沒(méi)有執(zhí)行,3.0的循環(huán)依賴(lài)處理和node一樣了#1382氧骤,下面的代碼可以用來(lái)測(cè)試這個(gè)問(wèn)題呻疹。

seajs.use("a" , function(a){
    a.doSomething();
});

//a.js
define(function(require, exports , module) {
    var b = require("b");
    exports.doSomething = function() {
        console.log("in a");
    };
});

//b.js
define(function(require, exports, module) {
    var c = require("c");
    exports.doSomething = function() {
        console.log("in b");
    };
});

//c.js
define(function(require, exports, module) {
    var a = require("a");
    exports.doSomething = function() {
        console.log("in c");
    };
});

提煉一下上面描述的內(nèi)容就是:對(duì)于一個(gè)模塊M,它應(yīng)該擁有下面的關(guān)系

Module{
a: {Module依賴(lài)的模塊}
b: {依賴(lài)Module的模塊}
}

在看看seajs中Module的定義:

function Module(uri, deps) {
  this.uri = uri
  this.dependencies = deps || []//我依賴(lài)的模塊
  this.exports = null
  this.status = 0   //我當(dāng)前的狀態(tài)
  this._waitings = {} //依賴(lài)我的模塊
  this._remain = 0  //我依賴(lài)的模塊還有多少?zèng)]有完成加載
}

以一個(gè)實(shí)際的例子說(shuō)明一下seajs模塊加載的邏輯筹陵,如下圖:

百度腦圖
  • a依賴(lài)b和c
  • b依賴(lài)d

盡管存在上述依賴(lài)刽锤,但是a,b朦佩,c并思,d模塊download到瀏覽器端的順序確是a,b语稠,c宋彼,d弄砍,而不是d,b输涕,c音婶,a,笨想一下后一種執(zhí)行順序也是不可能的莱坎,因?yàn)槟K間的依賴(lài)只有download到瀏覽器端seajs才能進(jìn)行分析衣式。

概括一下整個(gè)加載的流程就是:

自頂向下的download,自底向上的反饋準(zhǔn)備就緒檐什。

如何做到的呢碴卧?

  1. 主要是Module中的幾個(gè)屬性發(fā)揮的作用,模塊被download到瀏覽器端后乃正,按照CMD規(guī)范住册,define函數(shù)會(huì)被執(zhí)行,module.define會(huì)分析該模塊的依賴(lài)瓮具,記錄到dependencies屬性中界弧,define函數(shù)執(zhí)行完畢,綁定在script標(biāo)簽上的onload事件會(huì)被觸發(fā)搭综,進(jìn)而加載當(dāng)前模塊的依賴(lài)模塊垢箕,也就是執(zhí)行module.load函數(shù),這是一個(gè)循環(huán)往復(fù)的過(guò)程兑巾。

  2. 假設(shè)d模塊加載就緒条获,執(zhí)行module.load時(shí)發(fā)現(xiàn),d模塊已無(wú)其他依賴(lài)蒋歌,進(jìn)而執(zhí)行module.onload, 在module.onload中帅掘,通過(guò)_waitings屬性找到父模塊,操作父模塊的依賴(lài)計(jì)數(shù)_remain堂油,達(dá)到通知父模塊的目的修档。

這是一個(gè)完美的反饋系統(tǒng)。

seajs的模塊加載可以分為兩部分府框,一部分就是模塊加載的過(guò)程吱窝,另一部分就是模塊執(zhí)行的過(guò)程。相比較而言迫靖,執(zhí)行過(guò)程就比較簡(jiǎn)單了院峡,具體可以看源碼module.exec這個(gè)函數(shù)。

下一節(jié)分析seajs中模塊id的解析原理系宜。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末照激,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子盹牧,更是在濱河造成了極大的恐慌俩垃,老刑警劉巖励幼,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異口柳,居然都是意外死亡赏淌,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)啄清,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人俺孙,你說(shuō)我怎么就攤上這事辣卒。” “怎么了睛榄?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵荣茫,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我场靴,道長(zhǎng)啡莉,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任旨剥,我火速辦了婚禮咧欣,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘轨帜。我一直安慰自己魄咕,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布蚌父。 她就那樣靜靜地躺著哮兰,像睡著了一般。 火紅的嫁衣襯著肌膚如雪苟弛。 梳的紋絲不亂的頭發(fā)上喝滞,一...
    開(kāi)封第一講書(shū)人閱讀 51,125評(píng)論 1 297
  • 那天,我揣著相機(jī)與錄音膏秫,去河邊找鬼右遭。 笑死,一個(gè)胖子當(dāng)著我的面吹牛缤削,可吹牛的內(nèi)容都是我干的狸演。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼僻他,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼宵距!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起吨拗,我...
    開(kāi)封第一講書(shū)人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤满哪,失蹤者是張志新(化名)和其女友劉穎婿斥,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體哨鸭,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡民宿,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了像鸡。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片活鹰。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖只估,靈堂內(nèi)的尸體忽然破棺而出志群,到底是詐尸還是另有隱情,我是刑警寧澤蛔钙,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布锌云,位于F島的核電站,受9級(jí)特大地震影響吁脱,放射性物質(zhì)發(fā)生泄漏桑涎。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一兼贡、第九天 我趴在偏房一處隱蔽的房頂上張望攻冷。 院中可真熱鬧,春花似錦遍希、人聲如沸讲衫。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)涉兽。三九已至,卻和暖如春篙程,著一層夾襖步出監(jiān)牢的瞬間枷畏,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來(lái)泰國(guó)打工虱饿, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留拥诡,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓氮发,卻偏偏與公主長(zhǎng)得像渴肉,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子爽冕,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容