九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
以代碼愛(ài)好者角度來(lái)看AMD與CMD

  隨著瀏覽器功能越來(lái)越完善,前端已經(jīng)不僅僅是切圖做網(wǎng)站,前端在某些方面已經(jīng)媲美桌面應(yīng)用。越來(lái)越龐大的前端項(xiàng)目,越來(lái)越復(fù)雜的代碼,前端開(kāi)發(fā)者們對(duì)于模塊化的需求空前強(qiáng)烈。后來(lái)node出現(xiàn)了,跟隨node出現(xiàn)的還有commonjs,這是一種js模塊化解決方案,像Node.js主要用于服務(wù)器的編程,加載的模塊文件一般都已經(jīng)存在本地硬盤(pán),所以加載起來(lái)比較快,不用考慮異步加載的方式,CommonJS 加載模塊是同步的,所以只有加載完成才能執(zhí)行后面的操作。但是瀏覽器環(huán)境不同于Node,瀏覽器中獲取一個(gè)資源必須要發(fā)送http請(qǐng)求,從服務(wù)器端獲取,采用同步模式必然會(huì)阻塞瀏覽器進(jìn)程出現(xiàn)假死現(xiàn)象。在這方面dojo曾經(jīng)做了偉大嘗試,早期dojo便是采用xhr+eval的方式,結(jié)果可想而知,阻塞現(xiàn)象是必然的。后來(lái)出現(xiàn)無(wú)阻塞加載腳本方式在開(kāi)發(fā)中廣泛應(yīng)用,在此基礎(chǔ)結(jié)合commonjs規(guī)范,前端模塊化迎來(lái)了兩種方案:AMD、CMD.

  借用三藏法師一句話:人是人他媽生的,妖是妖他媽生的。此話雖不雅,但用這里卻頗為貼切。AMD 是 RequireJS 在推廣過(guò)程中對(duì)模塊定義的規(guī)范化產(chǎn)出,CMD是SeaJS 在推廣過(guò)程中被廣泛認(rèn)知。RequireJs出自dojo加載器的作者James Burke,SeaJs出自國(guó)內(nèi)前端大師玉伯。二者的區(qū)別,玉伯在12年如是說(shuō)

RequireJS 和 SeaJS 都是很不錯(cuò)的模塊加載器,兩者區(qū)別如下:1. 兩者定位有差異。RequireJS 想成為瀏覽器端的模塊加載器,同時(shí)也想成為 Rhino / Node 等環(huán)境的模塊加載器。SeaJS 則專注于 Web 瀏覽器端,同時(shí)通過(guò) Node 擴(kuò)展的方式可以很方便跑在 Node 服務(wù)器端2. 兩者遵循的標(biāo)準(zhǔn)有差異。RequireJS 遵循的是 AMD(異步模塊定義)規(guī)范,SeaJS 遵循的是 CMD (通用模塊定義)規(guī)范。規(guī)范的不同,導(dǎo)致了兩者 API 的不同。SeaJS 更簡(jiǎn)潔優(yōu)雅,更貼近 CommonJS Modules/1.1 和 Node Modules 規(guī)范。3. 兩者社區(qū)理念有差異。RequireJS 在嘗試讓第三方類(lèi)庫(kù)修改自身來(lái)支持 RequireJS,目前只有少數(shù)社區(qū)采納。SeaJS 不強(qiáng)推,而采用自主封裝的方式來(lái)“海納百川”,目前已有較成熟的封裝策略。4. 兩者代碼質(zhì)量有差異。RequireJS 是沒(méi)有明顯的 bug,SeaJS 是明顯沒(méi)有 bug。5. 兩者對(duì)調(diào)試等的支持有差異。SeaJS 通過(guò)插件,可以實(shí)現(xiàn) Fiddler 中自動(dòng)映射的功能,還可以實(shí)現(xiàn)自動(dòng) combo 等功能,非常方便便捷。RequireJS 無(wú)這方面的支持。6. 兩者的插件機(jī)制有差異。RequireJS 采取的是在源碼中預(yù)留接口的形式,源碼中留有為插件而寫(xiě)的代碼。SeaJS 采取的插件機(jī)制則與 Node 的方式一致:開(kāi)放自身,讓插件開(kāi)發(fā)者可直接訪問(wèn)或修改,從而非常靈活,可以實(shí)現(xiàn)各種類(lèi)型的插件。.

  關(guān)于二者的區(qū)別,前人之述備矣:

  而在本文,我們僅從代碼愛(ài)好者的角度來(lái)一窺二者API、模塊管理、加載、執(zhí)行的異同。

  對(duì)比AMD與CMD規(guī)范,二者最大的區(qū)別在于依賴模塊的執(zhí)行時(shí)期,CMD規(guī)范中明確要求延遲執(zhí)行(Execution must be lazy.)。這一點(diǎn)從二者在模塊的定義方法define的函數(shù)簽名上可以看出:

  AMD中define如下定義:
   define(id?, dependencies?, factory);
  •  id:String類(lèi)型,它指定了模塊被定義時(shí)的id;可選的,如果省略,模塊id默認(rèn)使用加載器請(qǐng)求的響應(yīng)腳本的模塊id。
  • dependencies是一個(gè)模塊定義時(shí)要求的依賴項(xiàng)的模塊id數(shù)組字面量。這些依賴項(xiàng)必須在factory方法執(zhí)行前被解析,解析值應(yīng)當(dāng)被當(dāng)做參數(shù)傳遞給factory函數(shù);factory的參數(shù)位置符合模塊在依賴項(xiàng)中的索引。
  • factory,是一個(gè)被用來(lái)執(zhí)行模塊初始化的參數(shù)或者是一個(gè)對(duì)象。如果factory是一個(gè)函數(shù),它應(yīng)當(dāng)只能被用來(lái)執(zhí)行一次。如果factory參數(shù)是一個(gè)對(duì)象,這個(gè)對(duì)象唄用來(lái)作為模塊的輸出值。如果factory函數(shù)返回一個(gè)值(對(duì)象、函數(shù)、任何可以被強(qiáng)制轉(zhuǎn)換為true的值),這個(gè)值將會(huì)被作為模塊的輸出值。

 

define(["./a", "./b"], function(a, b) {  //BEGIN  a.doSomething();  b.doSomething();});

 

  CMD中模塊如下定義:

define(function(require, exports, module) {  // The module code goes here});
  一個(gè)模塊使用define函數(shù)來(lái)定義
  1. define函數(shù)只接受一個(gè)模塊工廠作為參數(shù)
  2. factory必須是一個(gè)函數(shù)或者其他有效值
  3. 如果factory是一個(gè)函數(shù),如果指定參數(shù)的話,前三個(gè)必須是“require”,“exports”,“module”
  4. 如果factory不是一個(gè)函數(shù),那么模塊的exports屬性被設(shè)置為那個(gè)有效對(duì)象
define(function(require, exports, module) {  //BEGIN  require("./a").doSomething();  require("./b").doSomething();});

  需要提一下的是二者對(duì)待依賴模塊的加載是一致的,在factory執(zhí)行時(shí),依賴模塊都已被加載。從代碼上來(lái)看,AMD中在BEGIN處a、b的factory都是執(zhí)行過(guò)的;而CMD中雖然a、b模塊在BEGIN已被加載,但尚未執(zhí)行,需要調(diào)用require執(zhí)行依賴模塊。這就是CMD中著重強(qiáng)調(diào)的延遲執(zhí)行。如果這個(gè)例子不明顯的話,我們來(lái)看一下條件依賴:

  AMD:

define(["./a", "./b"], function(a, b) {  //BEGIN  if (true) {    a.doSomething();  } else {b.doSomething();  }  //END});

  CMD:

define(function(require) {   // BEGIN  if(some_condition) {    require('./a').doSomething();  } else {    require('./b').soSomething();  }  // END});

  條件依賴意思是我們根據(jù)條件使用依賴項(xiàng),在AMD中BEGIN位置處a、b模塊都需要被執(zhí)行一次。CMD中BEGIN處a、b都沒(méi)有被執(zhí)行,在END處,a、b只有一個(gè)被實(shí)際執(zhí)行過(guò)。

 

  那么問(wèn)題來(lái)了,javascript作為腳本語(yǔ)言,代碼肯定是順序執(zhí)行的,作為AMD與CMD的實(shí)現(xiàn)者,requireJs與seaJs是如何知道需要加載的所有文件呢?又是如何做到異步加載?對(duì)于seajs,factory中代碼肯定是順序執(zhí)行的,但是這必須導(dǎo)致require時(shí)的阻塞加載,而她又是如何保證異步加載的?

  每一個(gè)卓越的思想都有一份樸實(shí)的代碼實(shí)現(xiàn)。所以無(wú)論AMD與CMD都要面臨以下幾個(gè)問(wèn)題:

  1、模塊式如何注冊(cè)的,define函數(shù)都做了什么?
  2、他們是如何知道模塊的依賴?
  3、如何做到異步加載?尤其是seajs如何做到異步加載延遲執(zhí)行的?
  辯證法第一規(guī)律:事物之間具有有機(jī)聯(lián)系。AMD與CMD都借鑒了CommonJs,宏觀層面必有一致性,比如整體處理流程:
  模塊的加載解析到執(zhí)行過(guò)程一共經(jīng)歷了6個(gè)步驟:
  1、由入口進(jìn)入程序
  2、進(jìn)入程序后首先要做的就是建立一個(gè)模塊倉(cāng)庫(kù)(這是防止重復(fù)加載模塊的關(guān)鍵),JavaScript原生的object對(duì)象最為適合,key代表模塊Id,value代表各個(gè)模塊,處理主模塊
  3、向模塊倉(cāng)庫(kù)注冊(cè)一模塊,一個(gè)模塊最少包含四個(gè)屬性:id(唯一標(biāo)識(shí)符)、deps(依賴項(xiàng)的id數(shù)組)、factory(模塊自身代碼)、status(模塊的狀態(tài):未加載、已加載未執(zhí)行、已執(zhí)行等),放到代碼中當(dāng)然還是object最合適
  4、模塊即是JavaScript文件,使用無(wú)阻塞方式(動(dòng)態(tài)創(chuàng)建script標(biāo)簽)加載模塊
scriptElement= document.createElement('script');scriptElement.src = moduleUrl;scriptElement.async = true;scriptElement.onload = function(){.........};document.head.appendChild(scriptElement);

  5、模塊加載完畢后,獲取依賴項(xiàng)(amd、cmd區(qū)別),改變模塊status,由statuschange后,檢測(cè)所有模塊的依賴項(xiàng)。

  由于requirejs與seajs遵循規(guī)范不同,requirejs在define函數(shù)中可以很容易獲得當(dāng)前模塊依賴項(xiàng)。而seajs中不需要依賴聲明,所以必須做一些特殊處理才能否獲得依賴項(xiàng)。方法將factory作toString處理,然后用正則匹配出其中的依賴項(xiàng),比如出現(xiàn)require(./a),則檢測(cè)到需要依賴a模塊。

  同時(shí)滿足非阻塞和順序執(zhí)行就需要需要對(duì)代碼進(jìn)行一些預(yù)處理,這是由于CMD規(guī)范和瀏覽器環(huán)境特點(diǎn)所決定的。

  6、如果模塊的依賴項(xiàng)完全加載完畢(amd中需要執(zhí)行完畢,cmd中只需要文件加載完畢,注意這時(shí)候的factory尚未執(zhí)行,當(dāng)使用require請(qǐng)求該模塊時(shí),factory才會(huì)執(zhí)行,所以在性能上seajs遜于requirejs),執(zhí)行主模塊的factory函數(shù);否則進(jìn)入步驟3.

 

  最后,無(wú)論requireJs還是seaJs都已被廣泛應(yīng)用于web開(kāi)發(fā)中,實(shí)際選取時(shí)應(yīng)根據(jù)以下幾方面綜合平衡選?。?/span>

  1、功能能否滿足項(xiàng)目需求
  2、文檔、demo的詳盡程度
  3、框架的學(xué)習(xí)曲線
  4、社區(qū)的活躍度

 

  如果您覺(jué)得這篇文章對(duì)您有幫助,請(qǐng)不吝點(diǎn)擊推薦。

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
js模塊化歷程
CommonJS,AMD,CMD區(qū)別
前端模塊化開(kāi)發(fā)(AMD和CDM規(guī)范)
詳解JavaScript模塊化開(kāi)發(fā)
jQuery 對(duì)AMD的支持(Require.js中如何使用jQuery) – WEB前端開(kāi)發(fā)
淺析JS中的模塊規(guī)范(CommonJS,AMD,CMD)
更多類(lèi)似文章 >>
生活服務(wù)
熱點(diǎn)新聞
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服