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 相关文章推荐
提高NodeJS中SSL服务的性能
Jul 15 NodeJs
Nodejs极简入门教程(一):模块机制
Oct 25 NodeJs
nodejs实现遍历文件夹并统计文件大小
May 28 NodeJs
Nodejs初级阶段之express
Nov 23 NodeJs
NodeJS中的MongoDB快速入门详细教程
Nov 11 NodeJs
详解nodejs微信公众号开发——2.自动回复
Apr 10 NodeJs
手把手教你把nodejs部署到linux上跑出hello world
Jun 19 NodeJs
浅谈NodeJs之数据库异常处理
Oct 25 NodeJs
nodejs实现爬取网站图片功能
Dec 14 NodeJs
nodejs结合socket.io实现websocket通信功能的方法
Jan 12 NodeJs
NodeJS使用Range请求实现下载功能的方法示例
Oct 12 NodeJs
深入理解NodeJS 多进程和集群
Oct 17 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 @ at 记号的作用示例介绍
2014/10/10 PHP
php自定义hash函数实例
2015/05/05 PHP
php+mongodb判断坐标是否在指定多边形区域内的实例
2016/10/28 PHP
js checkbox(复选框) 使用集锦
2009/04/28 Javascript
多浏览器兼容的获取元素和鼠标的位置的js代码
2009/12/15 Javascript
web前端开发也需要日志
2010/12/09 Javascript
jQuery中读取json文件示例代码
2013/05/10 Javascript
jquery查找父元素、子元素(个人经验总结)
2014/04/09 Javascript
js类定义函数时用prototype与不用的区别示例介绍
2014/06/10 Javascript
json实现前后台的相互传值详解
2015/01/05 Javascript
prettier自动格式化去换行的实现代码
2020/08/25 Javascript
JS实现炫酷轮播图
2020/11/15 Javascript
three.js如何实现3D动态文字效果
2021/03/03 Javascript
[02:54]DOTA2英雄基础教程 暗影牧师戴泽
2013/12/05 DOTA
解决Python中由于logging模块误用导致的内存泄露
2015/04/23 Python
Python cx_freeze打包工具处理问题思路及解决办法
2016/02/13 Python
使用py2exe在Windows下将Python程序转为exe文件
2016/03/04 Python
浅谈python字典多键值及重复键值的使用
2016/11/04 Python
Python中shutil模块的学习笔记教程
2017/04/04 Python
pyqt5自定义信号实例解析
2018/01/31 Python
详解django中使用定时任务的方法
2018/09/27 Python
Python Pywavelet 小波阈值实例
2019/01/09 Python
python selenium firefox使用详解
2019/02/26 Python
浅析Python 引号、注释、字符串
2019/07/25 Python
python实现超市商品销售管理系统
2019/10/25 Python
python检查目录文件权限并修改目录文件权限的操作
2020/03/11 Python
selenium+python配置chrome浏览器的选项的实现
2020/03/18 Python
python输出结果刷新及进度条的实现操作
2020/07/13 Python
python实现KNN近邻算法
2020/12/30 Python
铁路个人事迹材料
2014/01/30 职场文书
五四青年节优秀演讲稿范文
2014/05/28 职场文书
病人家属写给医院的感谢信
2015/01/23 职场文书
python中pandas.read_csv()函数的深入讲解
2021/03/29 Python
CSS3 实现的图片悬停的切换按钮
2021/04/13 HTML / CSS
晶体管单管来复再生式收音机
2021/04/22 无线电
在Python中如何使用yield
2021/06/07 Python