乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      對(duì)CommonJS,AMD,CMD規(guī)范以及script標(biāo)簽異步加載的理解

       印度阿三17 2019-05-19
      1.牢騷

      CommonJS, AMD, CMD , 其實(shí)很早就接觸過(guò)了。
      當(dāng)時(shí), 網(wǎng)上的文章看得眼花繚亂, 只依稀記得幾個(gè)模糊的概念。
      什么依賴前置 , 什么按需加載。
      一頭霧水。

      現(xiàn)在再回過(guò)頭來(lái)看看概念 , 網(wǎng)上部分文章用詞模棱兩可。
      給我們這些菜雞, 帶來(lái)了理解的偏差和困惑。
      記得第一個(gè)項(xiàng)目還用了requireJS 。
      時(shí)過(guò)境遷,現(xiàn)在入門前端 , 都是直接上webpack了 。
      但我覺(jué)得還是有必要理一理 。


      2. 是什么

      CommonJS, AMD, CMD是規(guī)范, 理念 ;

      • 對(duì) CommonJS 的實(shí)現(xiàn) , 有 node 的模塊系統(tǒng) ;

      • 對(duì) AMD 的實(shí)現(xiàn)有require.js ;

      • 而 CMD, 是在sea.js的實(shí)現(xiàn)中提出來(lái)的 (但是在Google和Stack Overflow, 這個(gè)概念很少被提到, 一般出現(xiàn)在國(guó)內(nèi))


      • CommonJS規(guī)范, 模塊加載是同步的
        對(duì)node來(lái)說(shuō),模塊存放在本地硬盤,同步加載,等待時(shí)間就是硬盤的讀取時(shí)間,這個(gè)時(shí)間非常短;

      • AMD、CMD 規(guī)范,模塊加載是異步的
        目的, 是為了適應(yīng)瀏覽器環(huán)境,加載的時(shí)間取決于網(wǎng)絡(luò)的好壞,可能要等很長(zhǎng)時(shí)間;


      3. 先說(shuō) async 和 defer

      記得看文章的時(shí)候, 看到了下面這段話 ,
      在這里插入圖片描述
      我看了半天, 總覺(jué)得不是很理解 , 為什么呢 ?
      這里說(shuō), 腳本標(biāo)簽天生是異步的 , 那為什么會(huì)出現(xiàn) async 和 defer ?
      然后, 我發(fā)覺(jué)我并沒(méi)有把 加載執(zhí)行的概念區(qū)分清楚 , 這里的加載我把它理解為瀏覽器中的下載
      這里貼一張圖就很清楚了:
      defer和async

      • <script> 標(biāo)簽, 在下載和執(zhí)行的時(shí)候 , 會(huì)阻塞dom的渲染進(jìn)程 , 所以如果把<script> 標(biāo)簽放在<head>中, 當(dāng) js 文件很大或者網(wǎng)絡(luò)差時(shí), 會(huì)導(dǎo)致頁(yè)面長(zhǎng)時(shí)間空白( 順帶提一下, <script>標(biāo)簽并不會(huì)阻止其他的<script>標(biāo)簽的下載, 現(xiàn)代瀏覽器中多個(gè)<script>下載是并行的, 在chrome中, 默認(rèn)支持6個(gè)資源(http1.x)并行下載 ), 另外 , 腳本是按照<script>標(biāo)簽的書寫順序執(zhí)行的 ;

      • <script defer> 在加上defer以后, 下載的過(guò)程就不會(huì)阻塞dom渲染了, 但腳本的執(zhí)行是在dom渲染完畢之后;

      • <script async>在加上async以后, 下載的過(guò)程同樣不會(huì)阻塞dom渲染, 但腳本會(huì)在下載完后立刻執(zhí)行, 所以存在多個(gè)<script async>時(shí), 無(wú)法保證多個(gè)js文件的執(zhí)行順序, 加載較快的腳本會(huì)執(zhí)行;

      所以defer, async主要作用于加載階段, 執(zhí)行階段仍然會(huì)阻塞dom渲染


      4. 再看 require.js 的異步體現(xiàn)

      再看看使用require.js的模塊寫法
      新建 main.js / a.js / b.js , main.js 為入口, 引用了a.js , b.js

      	// main.js
      	// waitSeconds = 0的配置, 是為了防止文件過(guò)大或網(wǎng)絡(luò)不佳時(shí), 加載時(shí)間過(guò)長(zhǎng)導(dǎo)致require報(bào)`Load timeout for modules`的錯(cuò)誤 
      	require.config({
         		 waitSeconds: 0
        	});
      	require(['a.js', 'b.js'], function(a, b){
      		// handle / use a, b
      		console.log(a)
      		console.log(b)
      	})
      	
      	// a.js   ------------------------------
      	define([], function(){
      		return {
      			a: 111111111111
      		}
      	})
      	
      	// b.js   ------------------------------
      	define([], function(){
      		return {
      			b: 222222222222
      		}
      	})	
      
      • 文件 開始下載 的 順序: main, a, b
        為什么文件下載的順序是 main, a, b 呢? main依賴了 a b, 不是 a b 先下載嗎? 那是因?yàn)?,只?main 加載之后,才知道m(xù)ian依賴了啥啊

      • 執(zhí)行的 順序 : a, b, main 或者 b, a, main
        這里體現(xiàn) require.js 的異步加載。 a 和 b 的加載或者說(shuō)下載是并行的, 但 a 和 b 的執(zhí)行順序不確定的 , a 和 b 先執(zhí)行哪一個(gè)都無(wú)所謂 ,只需要保證回調(diào)函數(shù)在 a 和 b 都執(zhí)行完之后再執(zhí)行就可以了;

      在require.js中模塊加載是怎么實(shí)現(xiàn)的呢?
      看一下require.js的源碼:

          /**
           * Creates the node for the load command. Only used in browser envs.
           */
          req.createNode = function (config, moduleName, url) {
              var node = config.xhtml ?
                      document.createElementNS('http://www./1999/xhtml', 'html:script') :
                      document.createElement('script');
              node.type = config.scriptType || 'text/javascript';
              node.charset = 'utf-8';
              node.async = true;   
              return node;
          };

      這段代碼, 新建了script標(biāo)簽, 并把它的 async設(shè)置為true ,

      另外, 前面說(shuō) , 依賴的模塊都執(zhí)行完之后, 才會(huì)執(zhí)行回調(diào)函數(shù)。 那怎么判斷是否 所有依賴的模塊 都已經(jīng)執(zhí)行完 ?
      多個(gè)模塊的情況 , 還沒(méi)看懂(捂臉) , 但是單個(gè)模塊的執(zhí)行狀態(tài)是可以監(jiān)聽的:

      	...
      	...
      	...
              //mentioned above about not doing the 'script execute,
              //then fire the script load event listener before execute
              //next script' that other browsers do.
              //Best hope: IE10 fixes the issues,
              //and then destroys all installs of IE 6-9.
              //node.attachEvent('onerror', context.onScriptError);
          } else {
              node.addEventListener('load', context.onScriptLoad, false);
              node.addEventListener('error', context.onScriptError, false);
          }
          node.src = url;
          ...
          ...

      上面的代碼可以看到, 通過(guò) <script>標(biāo)簽的onload事件可以判斷, 該腳本是否執(zhí)行完畢 ;

      所以, 個(gè)人理解, require.js的異步
      第一, 是指下載的異步,
      第二, 還指回調(diào)機(jī)制, 依賴模塊執(zhí)行完之后再執(zhí)行回調(diào)函數(shù)

      5. AMD 和 CMD 的理解誤區(qū)

      現(xiàn)在 再來(lái)看 AMD 和 CMD 的區(qū)別, 網(wǎng)上的說(shuō)法:

      1. AMD推崇依賴前置,在定義模塊的時(shí)候就要聲明其依賴的模塊

      2. CMD推崇就近依賴,只有在用到某個(gè)模塊的時(shí)候再去require

      第二點(diǎn) 只有在用到某個(gè)模塊的時(shí)候再去require, 這種說(shuō)其實(shí)是帶有誤導(dǎo)性的,
      看看sea.js的寫法:

      	define(function(require, exports, module) {  
      		console.log(123) 
      	    var a = require('a.js')
      	    console.log(a)
      	    var b = require('b.js')
      	    console.log(b)
      	})

      這里, 難道是執(zhí)行到require, 才去加載/下載require的文件嗎 ?
      當(dāng)然不是 ! 看一下sea.js的代碼:

      	window.define = function(callback) {
          	var id = getCurrentJs()
          	var depsInit = s.parseDependencies(callback.toString())
          	var a = depsInit.map(item => basepath   item)
          ....

      sea.js把callback回調(diào)函數(shù)用轉(zhuǎn)換成字符串, 再找出有哪些依賴, 這些依賴模塊同樣是預(yù)先加載的 ,
      不同在于, require.js會(huì)立刻執(zhí)行依賴模塊, 而sea.js 在遇到 require 語(yǔ)句的時(shí)候 , 再執(zhí)行依賴模塊;

      5. 總結(jié)

      AMD和CMD最大的區(qū)別是: 對(duì)依賴模塊的執(zhí)行時(shí)機(jī)處理不同(注意不是加載的時(shí)機(jī))
      很多人說(shuō), requireJS是異步加載模塊,SeaJS是同步加載模塊,這么說(shuō)實(shí)際上是不準(zhǔn)確的 ;
      二者加載模塊都是異步的 ;
      只不過(guò)AMD依賴前置,可以方便知道依賴了哪些模塊,然后馬上加載 , 在加載完成后, 就會(huì)執(zhí)行該模塊;
      而CMD推崇就近依賴,把模塊變?yōu)樽址馕鲆槐? 找到依賴了哪些模塊, 在加載模塊完成后, 不立刻執(zhí)行, 而是等到require后再執(zhí)行;
      上面只說(shuō)了異步相關(guān)的概念, 其實(shí) require.js / sea.js , 最重要的還是模塊化。
      模塊化降低耦合,依賴清晰,讓調(diào)試, 加功能, 任務(wù)分配和交接都更方便。

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多