从头开始写框架(二):孕育框架的种子_中

上一篇我们介绍了AMD规范,异步模块的定义与加载,我们完成了定义的部分。接下来,我们来完成加载的部分。

我们之前已经可以用define来定义模块了,那么现在怎么去使用的?我们只是把定义好的模块存进了仓库,用的时候还需要一个方法来使用它。

让我们先来用define来定义一些模块:

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)

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方法是不能直接使用的,因为我们的模块是定义在了工厂方法的参数中,而这两个方法是被定义在了工厂方法内部中,所以我们是获取不到的。

那么让我们来改造一下这两个方法

这个出自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); //返回第一个模块的调用

  

这个方法直接把定义模块的函数放到了工厂方法的参数里,简化了很多程序,调用也更方便了。那么接下来就剩下怎样将框架模块与方法注册到命名空间上了。

这部分我们放到下一篇来写。

时间: 2024-08-24 01:24:39

从头开始写框架(二):孕育框架的种子_中的相关文章

腾讯高级工程师:如何从头开始写游戏服务器框架_转

转自: 腾讯高级工程师:如何从头开始写游戏服务器框架 本文作者:韩伟,腾讯互娱高级工程师,目前在 Next 产品中心研发创新类型游戏. 前言:从去年开始作者投入了一些具体游戏项目的开发,这些新的游戏项目,比较接近独立游戏的开发方式.在这个过程中,作者从头写了一个游戏服务器端的框架,以便获得更好的开发效率和灵活性.因此这篇文章便是该项目服务器框架的设计和实现过程的总结. PS:框架的基本运行环境是 Linux ,采用 C++ 编写.为了能在各种环境上运行和使用,采用了 gcc4.8 这个“古老”的

写自己的socket框架(二)

1.开始正常监听以后,就要开始接受数据了,整体流程图如下: 2.上一节看到我们在程序初始化的时候,初始化了很多个SocketConnection,用于管理客户端的链接,那应用层如何来操作,又什么时候来接受数据?于是我们便有了SocketSession,用于给应用层来管理整个会话过程,代码如下: public class SocketSession : IDisposable { public string SessionId { get; private set; } private Syste

企业级应用框架(二)三层架构之数据访问层的封装与抽象

接上一篇我们来对数据访问层进行封装与抽象.在上一篇我们知道,要解除BLL对DAL的依赖,我们就必须抽象出DAL层的接口,同时基于DAL的数据访问技术很多,如EF,ADO.NET,LINQ TO SQL,因此,我们的数据访问层必须对这些技术提供相应的支持.所以今天我们要做的事情有两件,第一,定义我们的数据访问层接口:第二,屏蔽各类数据库访问技术的差异,提供统一的数据库访问模型.举个例子,我们只需要修改一下我们的配置文件,就能够把ADO.NET的实现方式,改变成EF的实现方式.好下面搭建我们的三层构

百思不得姐框架(二)

一 该部分框架效果图和实现思路 框架二的效果图: 实现思路: -- 1> 先完善tabBar(主要是自定义) -- 2> 再完善导航条 -- 3> 其次完善屏幕侧滑(主要是全屏侧滑功能) 二 抽取分类(设置到插件中) 1 抽取分类的思想: 实现复用 --> 1.1 上部分代码中,我们需要设置tabBar中图片成未被渲染的格式,因此我们抽取了一个分类,用分类里面的方法实现了效果. --> 分类代码: //传入一张图片的名称返回一张未被渲染的图片 + (UIImage *)ori

用Asp.net写自己的服务框架

阅读目录 开始 理解Asp.net管线 HttpHandler HttpModule 关于Content-Encoding的解释 选 HttpHandler 还是 HttpModule ? 看不见的性能问题 更多实战介绍 实战演示 - 模拟更多的HttpMethod 实战演示 - URL重写 实战演示 - URL路由 实现自己的服务框架 利用[我的服务框架]将类公开成服务 [我的服务框架]支持的序列化的种类 [我的服务框架]对gzip的支持 利用[我的服务框架]发布服务的5种方式 我对发布服务的

我写的一个mvc框架讲解之一

从最原始的在jsp页面里面写代码到使用框架写代码,一路走来,大大小小的项目做了许多,接触过的mvc框架也有很多,目前开发界比较主流的mvc框架是struts2和spring mvc,都有各自缺点和优点,在项目使用过程中总有不尽人意的地方,下面主要讲解一下struts2和spring mvc在项目使用的不足之处,最终引入一个我自己写的一个mvc框架,虽然本框架还不够完善,也不敢说有多好,只是说比较合适于我的开发方式,并且已经在多个项目中使用.什么是mvc以及mvc原理,我不做讲解,自己百度 str

一步一步实现web程序信息管理系统之二----后台框架实现跳转登陆页面

SpringBoot springboot的目的是为了简化spring应用的开发搭建以及开发过程.内部使用了特殊的处理,使得开发人员不需要进行额外繁锁的xml文件配置的编写,其内部包含很多模块的配置只需要添加maven依赖即可使用,这项功能可谓对开发人员提供了大大的好处.使用springboot只需要简单配置一下就可以完成之前复杂的配置过程.可以到https://start.spring.io/此网站上,下载一个最简单的springboot应用,然后一步一步实现自已的应用. 可以看出当前的稳定版

自己写的轻量级PHP框架trig与laravel,yii性能对比

看了下当前最热门的php开发框架,想对比一下自己写的框架与这些框架的性能对比. 看结果对比. laravel 5.1: yii2: trig: 自己写的框架速度是lavavel 5.1的8倍,是yii2的5.3倍.

django框架&lt;二&gt;

django框架:   Models 1.基本创建 Django提供了一个抽象层("Model")的构建和管理Web应用程序的数据. Django使用一种新的方式,即:关系对象映射(Object Relational Mapping,简称ORM). 每个模型是一个Python类,子类django.db.models.model 模型中的每个属性代表一个数据库字段. # DEMO class Student(models.Model): name = models.CharField(m