NodeJS学习笔记之Connect中间件模块(二)


Posted in NodeJs onJanuary 27, 2015

一,开篇分析

大家好,今天这篇文章主要是对"Connect"中间件以及相关辅助中间件,做一个源码分析系列,我想上一篇文章大家也看了,

介绍了使用方式及用途,而这篇也是出于本人的兴趣,让读者对其有一个更深入的认识,如在分析阶段有什么不正确的地方,请大家多多指教,

好了!老规矩然我们进入正题。先来看一个例子,结合会用引入分析,如下:

 var connect = require("./lib/connect") ;

 var app = connect.createServer() ;

 app.use(connect.static(__dirname + "/public",{

    maxAge: 0 

})) ;

 app.use(function(req,res,next){

     res.end("Hello World !") ;

 })

 .listen(8888) ;
 

二,逐行分析:

(1),第一行,引入"connect"模块,通过connect创建一个http|https server,提供http server的所有功能。

"connect"中间件允许你用多种方式创建"server",

 

var server = connect.createServer(

     connect.logger()

    , connect.static(__dirname + '/public')

) ; // 1

var app = connect() ;

app.use(function (req,res) {

    res.end("Hello,大雄君 !\n")  ;

}).listen(8888)  ; // 2

那么它是如何做的那,看源码:

exports = module.exports = createServer ;

exports.createServer = createServer ;

将“createServer”挂载到全局的“exports”上,然后再扩展一个“createServer”属性再次挂载,目的是为了兼容原生的书写形式,

达到了不同方式创建的目的。这也是大家在平时开发中可以借鉴的思想。

(2),再来看第二行"connect.createServer",做了什么那,看如下源码:

 var HTTPServer = require('./http').Server , 

 HTTPSServer = require('./https').Server ;

 function createServer() {

   if ('object' == typeof arguments[0]) {

     return new HTTPSServer(arguments[0], Array.prototype.slice.call(arguments, 1));

   } else {

     return new HTTPServer(Array.prototype.slice.call(arguments));

   }

 };

"HTTPSServer"和"HTTPServer"基本一致,只是"HTTPSServer"封装的https的方法。在"createServer"的时候,同样可以传递进去一系列的中间件,和随后引入的效果是一样的,不过却只能绑定到根目录上。

(3),继续看第三行"app.use()",做了什么那,看如下源码:

 var Server = exports.Server = function HTTPServer(middleware) {

   this.stack = [];

   middleware.forEach(function(fn){

     this.use(fn);

   }, this);

   http.Server.call(this, this.handle);

 };

 /**

  * Inherit from `http.Server.prototype`.

  */

 Server.prototype.__proto__ = http.Server.prototype;

“connect"是原型继承于"http server"的,它会用use到的中间件替换掉server的requestListener。

通过"connect.use(route, handle)"来对每一个路由添加中间件,这些中间件"handle"会与"route"绑定保存在一个"stack"里面,每次有"request"请求的时候,

遍历这个堆,找到对应"route"的"handle",执行"handle",如果"handle"最后调用了"next()",就会继续寻找并执行下一个匹配的"handle"。

通过封装"handle",可以很容易的在"connect"基础上添加更多的"middleware"。

 (4),最后看看"listen(8888)",它做些什么工作那?

很简单,通过继承底层的Server对象,赋予了"listen"的功能,监听特定端口。

Server.prototype.__proto__ = http.Server.prototype

 以下是”connect.js“的全部源码,为了节省篇幅,注释已全部删掉,如下图:

NodeJS学习笔记之Connect中间件模块(二)

补充一下:

 fs.readdirSync(__dirname + '/middleware').forEach(function(filename){

   if (/\.js$/.test(filename)) {

     var name = filename.substr(0, filename.lastIndexOf('.'));

     exports.middleware.__defineGetter__(name, function(){

       return require('./middleware/' + name);

     });

   }

 });

将"middleware"对象"exports",然后循环定义给"middleware"对象一种方法,这种方法是直接加载 "middleware" 文件夹中的.js文件模块。

利用:"exports.utils.merge(exports, exports.middleware)" 这句话将middleware中的方法直接exports了。

三,总结一下:

 (1),理解源码的设计意图,有助于在应用上得到最大化的收获。

 (2),看源码时,理解流程再去扣语法细节。

 (3),借鉴源码中的巧妙实现思想,但不要过渡设计,为了设计而设计。

 (4),明天继续分析相关中间件,不断更新中 。。。 。。。

NodeJs 相关文章推荐
使用upstart把nodejs应用封装为系统服务实例
Jun 01 NodeJs
ubuntu下安装nodejs以及升级的办法
May 08 NodeJs
Nodejs实战心得之eventproxy模块控制并发
Oct 27 NodeJs
Nodejs基于LRU算法实现的缓存处理操作示例
Mar 17 NodeJs
详解nodejs微信公众号开发——5.素材管理接口
Apr 11 NodeJs
Nodejs中Express 常用中间件 body-parser 实现解析
May 22 NodeJs
理解nodejs的stream和pipe机制的原理和实现
Aug 12 NodeJs
nodejs项目windows下开机自启动的方法
Nov 22 NodeJs
nodejs简单实现TCP服务器端和客户端的聊天功能示例
Jan 04 NodeJs
Nodejs 和 Electron ubuntu下快速安装过程
May 04 NodeJs
利用nodeJs anywhere搭建本地服务器环境的方法
May 12 NodeJs
nodejs 如何手动实现服务器
Aug 20 NodeJs
NodeJS学习笔记之Connect中间件模块(一)
Jan 27 #NodeJs
nodejs批量修改文件编码格式
Jan 22 #NodeJs
NodeJS学习笔记之MongoDB模块
Jan 13 #NodeJs
NodeJS学习笔记之(Url,QueryString,Path)模块
Jan 13 #NodeJs
NodeJS学习笔记之FS文件模块
Jan 13 #NodeJs
NodeJS学习笔记之Http模块
Jan 13 #NodeJs
Nodejs学习笔记之Stream模块
Jan 13 #NodeJs
You might like
亲密接触PHP之PHP语法学习笔记1
2006/12/17 PHP
php xml文件操作代码(一)
2009/03/20 PHP
使用淘宝IP库获取用户ip地理位置
2013/10/27 PHP
PHP header()函数常用方法总结
2014/04/11 PHP
php随机显示指定文件夹下图片的方法
2015/07/13 PHP
PHP 数组遍历foreach语法结构及实例
2016/06/13 PHP
Javascript 去除数组的重复元素
2010/05/04 Javascript
asp.net 30分钟掌握无刷新 Repeater
2011/09/16 Javascript
web基于浏览器的本地存储方法应用
2012/11/27 Javascript
JS操作iframe里的dom(实例讲解)
2014/01/29 Javascript
jQuery对象和DOM对象之间相互转换的方法介绍
2015/02/28 Javascript
javascript结合canvas实现图片旋转效果
2015/05/03 Javascript
js实现跨域的4种实用方法原理分析
2015/10/29 Javascript
js实现简单排列组合的方法
2016/01/27 Javascript
Bootstrap入门书籍之(零)Bootstrap简介
2016/02/17 Javascript
原生js和css实现图片轮播效果
2017/02/07 Javascript
微信小程序 侧滑删除(左滑删除)
2017/05/23 Javascript
微信、QQ、微博、Safari中使用js唤起App
2018/01/24 Javascript
解决webpack多页面内存溢出的方法示例
2019/10/08 Javascript
vue-iview动态新增和删除的方法
2020/06/17 Javascript
three.js着色器材质的内置变量示例详解
2020/08/16 Javascript
[00:08]DOTA2勇士令状等级奖励“天外飞星”
2019/05/24 DOTA
Python实现去除图片中指定颜色的像素功能示例
2019/04/13 Python
Tensorflow训练MNIST手写数字识别模型
2020/02/13 Python
python 连续不等式语法糖实例
2020/04/15 Python
python实现猜单词游戏
2020/05/22 Python
python如何更新包
2020/06/11 Python
Python selenium键盘鼠标事件实现过程详解
2020/07/28 Python
土木工程实习生自我鉴定
2013/09/19 职场文书
大学生军训自我评价分享
2013/11/09 职场文书
机械专业毕业生推荐信范文
2013/11/25 职场文书
自我评价个人范文
2013/12/16 职场文书
2014年环卫工作总结
2014/11/22 职场文书
语文复习计划
2015/01/19 职场文书
观看焦裕禄观后感
2015/06/09 职场文书
2016元旦晚会主持词
2015/07/01 职场文书