<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                [TOC] ## 簡介 AMD 規范在這里: 中文:https://github.com/amdjs/amdjs-api/wiki/AMD-(%E4%B8%AD%E6%96%87%E7%89%88) 英文:http://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition AMD提出了一種基于模塊的異步加載JavaScript代碼的機制,它推薦開發人員將JavaScript代碼封裝進一個個模塊,對全局對象的依 賴變成了對其他模塊的依賴,無須再聲明一大堆的全局變量。 通過延遲和按需加載來解決各個模塊的依賴關系。模塊化的JavaScript代碼好處很明顯,各 個功能組件的松耦合性可以極大的提升代碼的復用性、可維護性。 這種非阻塞式的并發式快速加載JavaScript代碼,使Web頁面上其他不依賴 JavaScript代碼的UI元素,如圖片、CSS以及其他DOM節點得以先加載完畢,Web頁面加載速度更快,用戶也得到更好的體驗。 ## CMD 推崇異步加載,遵循依賴前置(加載前置)(提前加載) CMD 推崇依賴就近,AMD 推崇依賴前置。看代碼: ```js // CMD define(function(require, exports, module) { var a = require('./a') a.doSomething() // 此處略去 100 行 var b = require('./b') // 依賴可以就近書寫 b.doSomething() // ... }) // AMD 默認推薦的是 define(['./a', './b'], function(a, b) { // 依賴必須一開始就寫好 a.doSomething() // 此處略去 100 行 b.doSomething() //... }) ``` 雖然 AMD 也支持 CMD 的寫法,同時還支持將 require 作為依賴項傳遞,但 RequireJS 的作者默認是最喜歡上面的寫法,也是官方文檔里默認的模塊定義寫法。 ## define方法:定義模塊 作為一個規范,只需定義其語法API,而不關心其實現。CommonJS的AMD規范中只定義了一個全局的方法,即`define`函數: ```js  define([module-name?], [array-of-dependencies?], [module-factory-or-object]); ``` 其中: 1. `module-name`: 模塊標識,為文件名(沒有js后綴),可以省略。如果提供了該參數,模塊名必須是“頂級”的和絕對的(不允許相對名字)。 2. `array-of-dependencies`: 是一個字符串Array,表示該模塊依賴的其他所有模塊標識,模塊依賴必須在真正執行具體的factory方法前解決,這 些依賴對象加載執行以后的返回值,可以以默認的順序作為factory方法的參數。`array-of-dependencies` 也是可選參數,當用戶不提供該參數時,實現 AMD的框架應提供默認值為`[“require”,”exports”,“module”]`。所依賴的模塊,可以省略。 3. `module-factory-or-object`: 模塊的實現,或者一個JavaScript對象。 `module-name` 遵循 [CommonJS Module Identifiers](http://wiki.commonjs.org/wiki/Modules/1.1.1#Module_Identifiers) 。array-of-dependencies 元素的順序和 module-factory-or-object 參數一一對應。 從中可以看到,第一個參數和第二個參數都是可以省略的,第三個參數則是模塊的具體實現本身。后面將介紹在不同的應用場景下,他們會使用不同的參數組合。 CommonJS在規范中并沒有詳細規定其他的方法(只有define函數),一些主要的AMD框架如RequireJS、curl、bdload等都實現了define方法,同時各個框架都有自己的補充使得其API更實用。 ## 加載模塊的require方法(全局require) 實際中,我們經常會遇到一些阻塞模塊加載的依賴,如果交互次數很多,需要大量的模塊加載,應該采用**全局依賴**的形式去加載頂層模塊。 require方法用于調用模塊。它的參數與define方法類似。 ```js require(['foo', 'bar'], function ( foo, bar ) { foo.doSomething(); }); ``` 上面方法表示加載foo和bar兩個模塊,當這兩個模塊都加載成功后,執行一個回調函數。該回調函數就用來完成具體的任務。 require方法的第一個參數,是一個表示依賴關系的數組。這個數組可以寫得很靈活,請看下面的例子。 ```js require( [ window.JSON ? undefined : 'util/json2' ], function ( JSON ) { JSON = JSON || window.JSON; console.log( JSON.parse( '{ "JSON" : "HERE" }' ) ); }); ``` 上面代碼加載JSON模塊時,首先判斷瀏覽器是否原生支持JSON對象。如果是的,則將undefined傳入回調函數,否則加載util目錄下的json2模塊。 require方法也可以用在define方法內部。 ```js define(function (require) { var otherModule = require('otherModule'); }); ``` 下面的例子顯示了如何動態加載模塊。 ```js define(function ( require ) { var isReady = false, foobar; require(['foo', 'bar'], function (foo, bar) { isReady = true; foobar = foo() + bar(); }); return { isReady: isReady, foobar: foobar }; }); ``` 上面代碼所定義的模塊,內部加載了foo和bar兩個模塊,在沒有加載完成前,isReady屬性值為false,加載完成后就變成了true。因此,可以根據isReady屬性的值,決定下一步的動作。 下面的例子是模塊的輸出結果是一個promise對象。 ```js define(['lib/Deferred'], function( Deferred ){ var defer = new Deferred(); require(['lib/templates/?index.html','lib/data/?stats'], function( template, data ){ defer.resolve({ template: template, data:data }); } ); return defer.promise(); }); ``` 上面代碼的define方法返回一個promise對象,可以在該對象的then方法,指定下一步的動作。 如果服務器端采用JSONP模式,則可以直接在require中調用,方法是指定JSONP的callback參數為define。 ```js require( [ "http://someapi.com/foo?callback=define" ], function (data) { console.log(data); }); ``` require方法允許添加第三個參數,即錯誤處理的回調函數。 ```js require( [ "backbone" ], function ( Backbone ) { return Backbone.View.extend({ /* ... */ }); }, function (err) { // ... } ); ``` require方法的第三個參數,即處理錯誤的回調函數,接受一個error對象作為參數。 require對象還允許指定一個全局性的Error事件的監聽函數。所有沒有被上面的方法捕獲的錯誤,都會被觸發這個監聽函數。 ```js requirejs.onError = function (err) { // ... }; ``` `define`和`require`在依賴處理和回調執行上都是一樣的,不一樣的地方是define的回調函數需要有return語句返回模塊對象,這樣`define`定義的模塊才能被其他模塊引用;`require`的回調函數不需要return語句。 ## 局部require 局部require可以被解析成一個符合AMD工廠函數規范的require函數。 例如: ``` define(['require'], function (require) { // the require in here is a local require. }); define(function (require, exports, module) { // the require in here is a local require. }); ``` 局部require也支持其他標準實現的API: ```js define( function( require ){ var a = require('a'); // 加載模塊a } ); define( function( require ){ require( ['a', 'b'], function( a,b ){ // 加載模塊a b 使用 // 依賴 a b 模塊的運行代碼 } ); } ); define( function( require ){ var temp = require.toUrl('./temp/a.html'); // 加載頁面 } ); ``` ## AMD實例:如何定義一個模塊   下面代碼定義了一個alpha模塊,并且依賴于內置的require,exports模塊,以及外部的beta模塊。可以看到,第三個參數是回調函數,可以直接使用依賴的模塊,他們按依賴聲明順序作為參數提供給回調函數。   這里的require函數讓你能夠隨時去依賴一個模塊,即取得模塊的引用,從而即使模塊沒有作為參數定義,也能夠被使用;exports是定義的alpha 模塊的實體,在其上定義的任何屬性和方法也就是alpha模塊的屬性和方法。通過`exports.verb = ...`就是為alpha模塊定義了一個`verb`方法。 例子中是簡單調用了模塊beta的verb方法。 ```js define("alpha", ["require", "exports", "beta"], function (require, exports, beta) { exports.verb = function() { return beta.verb(); //或者: return require("beta").verb(); //require函數用來加載一個模塊 } }); ``` ## 實際應用 ```js //定義M模塊,本申明一個全局變量 define('M',[],function(){ window.M={}; return M; }) //定義模塊a 依賴模塊 M,b,c define('a',['M','b','c'],function(M){ alert(M.ob); alert(M.oc); }) //定義b模塊 define('b',[],function(){ M.ob = 2; return M; }) //定義c模塊 define('c',[],function(){ M.oc = 3; return M; }) //引入a模塊 require(['a'],function(a){ }) ``` ## CommonJS wrapping 其實是標準的AMD規范里面是完全兼容 CommonJs的,AMD本意是想統一前后端的,現在AMD一般在前端比較多。 為了復用已有的 CommonJS 模塊,AMD 規定了 [Simplified CommonJS wrapping](https://github.com/amdjs/amdjs-api/wiki/AMD#simplified-commonjs-wrapping-),然后 RequireJS 實現了它(先后順序不一定對)。它提供了類似于 CommonJS 的模塊定義方式,如下: ```js define(function(require, exports, module) { var A = require('a'); //就近定義 return function () {}; }); ``` 這樣,模塊的依賴可以像 CommonJS 一樣「就近定義」。但就是這個看上去兩全其美的做法,給大家帶來了很多困擾。 ### 困擾 ```js //mod1.js define(function() { console.log('require module: mod1'); return { hello: function() { console.log("hello mod1"); } }; }); JS //mod2.js define(function() { console.log('require module: mod2'); return { hello: function() { console.log("hello mod2"); } }; }); //main.js define(function(require, exports, module) { //CommonJS寫法 //運行至此,mod1.js 和 mod2.js 已經下載完成; console.log('require module: main'); var mod1 = require('./mod1'); //這里才執行 mod1 ? mod1.hello(); var mod2 = require('./mod2'); //這里才執行 mod2 ? mod2.hello(); return { hello: function() { console.log('hello main'); } }; }); ``` CommonJS Wrapper 只是書寫上兼容了 CommonJS 的寫法,模塊運行邏輯并不會改變。 因為 main.js 中 mod1 和 mod2 兩個模塊并行加載,且加載完就執行,所以前兩行輸出順序取決于哪個 js 先加載完。 這種「就近」書寫的依賴,非常容易讓人認為 main.js 執行到對應 require 語句時才執行 mod1 或 mod2,但這是錯誤的,因為 CommonJS Wrapper 并不會改變 AMD「盡早執行」依賴的本質! 實際上,對于按需執行依賴的加載器,如 [SeaJS](http://seajs.org/),上述代碼結果一定是: ~~~ require module: main require module: mod1 hello mod1 require module: mod2 hello mod2 hello main ~~~ 于是,了解過 CommonJS 或 CMD 模塊規范的同學,看到使用 CommonJS Wrapper 方式寫的 AMD 模塊,容易產生理解偏差,從而誤認為 RequireJS 有 bug。 我覺得「盡早執行」或「按需執行」兩種策略沒有明顯的優劣之分,但 AMD 這種「模仿別人寫法,卻提供不一樣的特性」這個做法十分愚蠢。 ## 具體實現 http://requirejs.org/ https://github.com/cujojs/curl ## 參考 https://imququ.com/post/amd-simplified-commonjs-wrapping.html https://github.com/amdjs/amdjs-api/wiki http://www.cnblogs.com/happyPawpaw/archive/2012/05/31/2528864.html http://www.jianshu.com/p/9b44a1fa8a96 [使用 AMD、CommonJS 及 ES Harmony 編寫模塊化的 JavaScript](http://justineo.github.io/singles/writing-modular-js/)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看