從頭開始寫框架(二):孕育框架的種子_中

上一篇咱們介紹了AMD規範,異步模塊的定義與加載,咱們完成了定義的部分。接下來,咱們來完成加載的部分。javascript

 

咱們以前已經能夠用define來定義模塊了,那麼如今怎麼去使用的?咱們只是把定義好的模塊存進了倉庫,用的時候還須要一個方法來使用它。html

讓咱們先來用define來定義一些模塊:java

define("a" , [] , function(){ //無依賴模塊
	return 1;
});

define("b" , ["a"] , function(a){ //有一個依賴的模塊
	return ++a;
});

define("c" , ["a","b"] , function(a,b){ //有兩個依賴的模塊  一會咱們要使用這個模塊
	return a+b;
});

  

這裏定義了3個模塊,其中有一個沒有依賴,兩個是存在依賴模塊的模塊。緩存

而後咱們須要一個方法來使用定義好的模塊:(對於apply和call方法不懂的話,能夠移步個人另外一篇文章:來聊聊apply和call)app

var noop = function(){}; //爲apply方法準備的一個空函數;
function use(name){ //參數:模塊名
	if(modules[name]){ // 若是模塊定義過:

		var module = modules[name]; //建立一個副本
		if(!module.entity){ //若是實例不存在,說明是第一次建立

			var args = [];

			for(var i=0;i<module.dependencies.length;i++){ //遍歷依賴列表

				modules[module.dependencies[i]].entity ?  //依賴模塊的實例以存在的話
				args.push(modules[module.dependencies[i]].entity) : //直接獲取實例(緩存方法),
				args.push(this.use(module.dependencies[i])); //否則單獨獲取一次

			};
			
			module.entity = module.fn.apply(noop , args); //用apply方法爲模塊實例擴展

		};

		return module.entity; //之後調用能夠直接調用緩存

	}else{

		throw new Error("Error:"+ name +" is not define"); // 若是沒有定義模塊,直接拋出一個錯誤.

	}
};

  

這裏咱們定義了一個使用模塊的方法,經過模塊名來調用定義過的模塊。而使用過一次的模塊,咱們把它存入緩存中,這樣之後再次使用時,直接調用它的實例就能夠了。框架

 

那麼接下來咱們來用這個方法來使用咱們定義好的模塊:異步

var d = use("c");
console.log(d)//輸出3

  

這樣咱們就能使用任意咱們定義過的模塊了,而從新定義模塊時,不會出現模塊名相同致使模塊被覆蓋的狀況。函數

那麼咱們怎麼用這個方法來擴展咱們的命名空間呢?顯然,define和use方法是不能直接使用的,由於咱們的模塊是定義在了工廠方法的參數中,而這兩個方法是被定義在了工廠方法內部中,因此咱們是獲取不到的。oop

那麼讓咱們來改造一下這兩個方法ui

這個出自Vuejs:

 

var moduleMap = {}; //模塊倉庫

		function require(ID){ //參數爲模塊的名字,這裏直接用數字來給模塊定義id

			if(moduleMap[ID]) //若是模塊已經存在
				return moduleMap[ID].exports;//直接返回實例,並結束代碼塊

			var module = moduleMap[ID] = { //聲明一個新對象
				exports:{},//初始化實例
				id:ID,
				loaded:false//初始化加載狀態
			};

			modules[ID].call(module.exports, module, module.exports, require); //用call方法將模塊擴展到倉庫中

			module.loaded = true; //設置模塊加載狀態
			
			return module.exports; //返回模塊實例
		};

		return require(0); //返回第一個模塊的調用

  

這個方法直接把定義模塊的函數放到了工廠方法的參數裏,簡化了不少程序,調用也更方便了。那麼接下來就剩下怎樣將框架模塊與方法註冊到命名空間上了。

 

 

這部分咱們放到下一篇來寫。

相關文章
相關標籤/搜索