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 相关文章推荐
Google官方支持的NodeJS访问API,提供后台登录授权
Jul 29 NodeJs
Windows系统下使用Sublime搭建nodejs环境
Apr 13 NodeJs
Nodejs初级阶段之express
Nov 23 NodeJs
详解NodeJs支付宝移动支付签名及验签
Jan 06 NodeJs
搭建简单的nodejs http服务器详解
Mar 09 NodeJs
nodejs读取并去重excel文件
Apr 22 NodeJs
nodejs 日志模块winston的使用方法
May 02 NodeJs
nodejs读取本地中文json文件出现乱码解决方法
Oct 10 NodeJs
NVM安装nodejs的方法实用步骤
Jan 16 NodeJs
nodejs npm错误Error:UNKNOWN:unknown error,mkdir 'D:\Develop\nodejs\node_global'at Error
Mar 02 NodeJs
nodejs制作小爬虫功能示例
Feb 24 NodeJs
Nodejs环境实现socket通信过程解析
Jul 03 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
星际实力自我测试
2020/03/04 星际争霸
PHP中preg_match函数正则匹配的字符串长度问题
2015/05/27 PHP
PHP实现简易blog的制作
2016/10/24 PHP
PHP+Ajax实现的检测用户名功能简单示例
2019/02/12 PHP
jQuery实现动画效果的实例代码
2013/05/07 Javascript
json数据与字符串的相互转化示例
2013/09/18 Javascript
通过action传过来的值在option获取进行验证的方法
2013/11/14 Javascript
jQuery使用$.ajax进行即时验证的方法
2015/12/08 Javascript
jQuery xml字符串的解析、读取及查找方法
2016/03/01 Javascript
JavaScript 轮播图和自定义滚动条配合鼠标滚轮分享代码贴
2016/10/28 Javascript
js实现图片切换(动画版)
2016/12/25 Javascript
jquery 正整数数字校验正则表达式
2017/01/10 Javascript
jQuery使用方法
2017/02/04 Javascript
Sublime Text新建.vue模板并高亮(图文教程)
2017/10/26 Javascript
基于Vue框架vux组件库实现上拉刷新功能
2017/11/28 Javascript
node实现的爬虫功能示例
2018/05/04 Javascript
ES6知识点整理之数组解构和字符串解构的应用示例
2019/04/17 Javascript
原生js+css实现tab切换功能
2020/09/17 Javascript
element-ui中dialog弹窗关闭按钮失效的解决
2020/09/22 Javascript
python通过urllib2爬网页上种子下载示例
2014/02/24 Python
以Flask为例讲解Python的框架的使用方法
2015/04/29 Python
Python排序算法之选择排序定义与用法示例
2018/04/29 Python
Python3.5实现的罗马数字转换成整数功能示例
2019/02/25 Python
Python发送邮件封装实现过程详解
2020/05/09 Python
让Django的BooleanField支持字符串形式的输入方式
2020/05/20 Python
HTML5的Video标签有部分MP4无法播放的问题解析(多图)
2017/08/18 HTML / CSS
Flesh Beauty官网:露华浓集团旗下彩妆品牌
2021/02/15 全球购物
中英文求职信范文
2014/01/27 职场文书
《美丽的公鸡》教学反思
2014/02/25 职场文书
消防安全责任书范本
2014/04/15 职场文书
心理健康日活动总结
2014/05/08 职场文书
神农溪导游词
2015/02/11 职场文书
本科毕业论文致谢怎么写
2015/05/14 职场文书
三国演义读书笔记
2015/06/25 职场文书
导游词之绍兴柯岩古镇
2020/01/09 职场文书
详细谈谈MYSQL中的COLLATE是什么
2021/06/11 MySQL