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
Nodejs实现多人同时在线移动鼠标的小游戏分享
Dec 06 NodeJs
nodejs中实现阻塞实例
Mar 24 NodeJs
nodejs实现遍历文件夹并统计文件大小
May 28 NodeJs
详谈Angular路由与Nodejs路由的区别
Mar 05 NodeJs
ubuntu编译nodejs所需的软件并安装
Sep 12 NodeJs
nodejs简单访问及操作mysql数据库的方法示例
Mar 15 NodeJs
nodejs基于express实现文件上传的方法
Mar 19 NodeJs
nodejs多版本管理总结
Apr 03 NodeJs
NodeJS实现自定义流的方法
Aug 01 NodeJs
关于NodeJS中的循环引用详解
Jul 23 NodeJs
windows如何把已安装的nodejs高版本降级为低版本(图文教程)
Dec 14 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 多行多列显示
2009/08/15 PHP
用php+ajax新建流程(请假、进货、出货等)
2017/06/11 PHP
Javascript下的keyCode键码值表
2007/04/10 Javascript
Code: write(s,d) 输出连续字符串
2007/08/19 Javascript
推荐11款jQuery开发的复选框和单选框美化插件
2011/08/02 Javascript
使用js实现按钮控制文本框加1减1应用于小时+分钟
2013/12/09 Javascript
禁止拷贝网页内容的js代码
2014/01/22 Javascript
JavaScript获取当前网页最后修改时间的方法
2015/04/03 Javascript
JS中使用apply方法通过不同数量的参数调用函数的方法
2016/05/31 Javascript
Web开发中客户端的跳转与服务器端的跳转的区别
2017/03/05 Javascript
页面缩放兼容性处理方法(zoom,Firefox火狐浏览器)
2017/08/29 Javascript
浅谈Koa服务限流方法实践
2017/10/23 Javascript
AngularJS实现的2048小游戏功能【附源码下载】
2018/01/03 Javascript
详解如何从零开始搭建Express+Vue开发环境
2018/07/17 Javascript
Javascript 之封装(Package)
2018/09/14 Javascript
vuex + axios 做登录验证 并且保存登录状态的实例
2018/09/16 Javascript
解决微信小程序防止无法回到主页的问题
2018/09/28 Javascript
JavaScript中的连续赋值问题实例分析
2019/07/12 Javascript
python使用正则表达式匹配字符串开头并打印示例
2017/01/11 Python
Python正确重载运算符的方法示例详解
2017/08/27 Python
python学习入门细节知识点
2018/03/29 Python
Tensorflow实现卷积神经网络的详细代码
2018/05/24 Python
Python中判断输入是否为数字的实现代码
2018/05/26 Python
python 使用turtule绘制递归图形(螺旋、二叉树、谢尔宾斯基三角形)
2019/05/30 Python
python之生产者消费者模型实现详解
2019/07/27 Python
浅谈Tensorflow 动态双向RNN的输出问题
2020/01/20 Python
pycharm无法导入本地模块的解决方式
2020/02/12 Python
python绘制分布折线图的示例
2020/09/24 Python
医学专业个人求职自荐信格式
2013/09/23 职场文书
实习教师自我鉴定
2013/09/27 职场文书
小学清明节活动方案
2014/03/08 职场文书
人民教师求职自荐信
2014/03/12 职场文书
行政人事岗位职责
2014/03/17 职场文书
交通事故代理词范文
2015/05/23 职场文书
MYSQL事务的隔离级别与MVCC
2022/05/25 MySQL
windows server 2012安装FTP并配置被动模式指定开放端口
2022/06/10 Servers