乘着週日有點時間,閱讀一下玉伯大神的源碼。html
seajs的源碼寫得真的很好,非常佩服,工整美觀不愧是大神,造福百姓。segmentfault
提及seajs不得不說,AMD和CMD的區別。app
<!DOCTYPE html> <html> <head> <title>seajs源碼閱讀</title> </head> <body> <script src="seajs-2.2.3/dist/sea-debug.js"></script> <script> seajs.use("./application",function(){ }) </script> </body> </html>
很簡單的代碼,使用application.js作主文件.下面是application.js源碼.requirejs
define(function(require,exports,module){ var test = require('ModuleTest'); });
application.js只依賴了ModuleTest.fetch
seajs.use爲入口.會先預加載,而後再調用Module.use.ui
seajs.use = function(ids, callback) { //預加載,預加載的模塊能夠經過seajs.config設置 Module.preload(function() { //開始了 Module.use(ids, callback, data.cwd + "_use_" + cid()) }) return seajs }
Module.use的代碼很關鍵.一開始會建立一個模塊就叫作入口模塊吧,這個模塊是沒有id的,並且這個模塊會依賴主模塊,更關鍵的是,這個入口模塊有callback,其餘模塊是沒有callback。spa
Module.use = function (ids, callback, uri) { var mod = Module.get(uri, isArray(ids) ? ids : [ids]) //模塊回調,加載完了以後就執行 mod.callback = function() { //...... } //加載模塊 mod.load() }
入口模塊的callback,最終會在Module.prototype.onload調用prototype
扯Module.prototype.onload,不得不扯Module.prototype.load.下面是load的流程.debug
大致流程:3d
demo中:
會建立入口模塊,設置入口模塊的callback,加載入口模塊。
因爲入口模塊依賴了"application模塊",就會fetch "application模塊",fetch成功就會調用"application模塊"中的define。
define會算出"application模塊"的依賴,也就是"ModuleTest模塊",而後回到load,繼續fetch "ModuleTest模塊"。
繼續回到"ModuleTest模塊"的load,這時候「ModuleTest模塊」的remain爲0,就會調用"ModuleTest模塊"的onload,而後根據waittings調用"application模塊"的onload。
最後就是入口模塊的onload.最後的最後,全部的模塊exec。KO。
吃完飯,再弄張圖,千言萬語不如一張圖。