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
基于 Docker 开发 NodeJS 应用
Jul 30 NodeJs
Windows系统中安装nodejs图文教程
Feb 28 NodeJs
使用nodejs中httpProxy代理时候出现404异常的解决方法
Aug 15 NodeJs
nodejs实现发出蜂鸣声音(系统报警声)的方法
Jan 18 NodeJs
Nodejs--post的公式详解
Apr 29 NodeJs
使用vs code开发Nodejs程序的使用方法
Sep 21 NodeJs
nodejs操作mongodb的增删改查功能实例
Nov 09 NodeJs
如何让Nodejs支持H5 History模式(connect-history-api-fallback源码分析)
May 30 NodeJs
Nodejs监听日志文件的变化的过程解析
Aug 04 NodeJs
nodejs各种姿势断点调试的方法
Jun 18 NodeJs
分享node.js实现简单登录注册的具体代码
Apr 26 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 5.5 创建和验证哈希最简单的方法详解
2013/11/07 PHP
php连接odbc数据源并保存与查询数据的方法
2014/12/24 PHP
PHP培训要多少钱
2017/06/06 PHP
用AJAX返回HTML片段中的JavaScript脚本
2010/01/04 Javascript
使用JavaScript switch case 另类写法
2010/03/14 Javascript
javascript 模式设计之工厂模式详细说明
2010/05/10 Javascript
javascript开发技术大全-第1章javascript概述
2011/07/03 Javascript
javascript写的简单的计算器,内容很多,方法实用,推荐
2011/12/29 Javascript
js自执行函数的几种不同写法的比较
2012/08/16 Javascript
JavaScript NaN和Infinity特殊值 [译]
2012/09/20 Javascript
Jquery实现显示和隐藏的4种简单方式
2013/08/28 Javascript
jquery实现图片水平滚动效果代码分享
2015/08/26 Javascript
实例详解JSON数据格式及json格式数据域字符串相互转换
2016/01/07 Javascript
Vue.js实现表格渲染的方法
2018/09/07 Javascript
jQuery easyui datagird编辑行删除行功能的实现代码
2018/09/20 jQuery
你不知道的Vue技巧之--开发一个可以通过方法调用的组件(推荐)
2019/04/15 Javascript
解决layui表格内文本超出隐藏的问题
2019/09/12 Javascript
使用jQuery实现掷骰子游戏
2019/10/24 jQuery
JS实现简单的表格增删
2020/01/16 Javascript
Vue父子传递实例讲解
2020/02/14 Javascript
对Python2与Python3中__bool__方法的差异详解
2018/11/01 Python
python+Selenium自动化测试——输入,点击操作
2020/03/06 Python
浅谈django channels 路由误导
2020/05/28 Python
python线性插值解析
2020/07/05 Python
用opencv给图片换背景色的示例代码
2020/07/08 Python
Python csv文件记录流程代码解析
2020/07/16 Python
HTML5 绘制图像(上)之:关于canvas元素引领下一代web页面的问题
2013/04/24 HTML / CSS
详解webapp页面滚动卡顿的解决办法
2018/12/26 HTML / CSS
英国最大的网上药品商店:Chemist Direct
2017/12/16 全球购物
市场营销毕业生自荐信范文
2014/04/01 职场文书
大学生个人先进事迹材料范文
2014/05/03 职场文书
班子群众路线教育实践个人对照检查材料思想汇报
2014/09/30 职场文书
质量保证书
2015/01/17 职场文书
2016年大学生党员公开承诺书
2016/03/24 职场文书
Mysql Online DDL的使用详解
2021/05/20 MySQL
详解PHP设计模式之依赖注入模式
2021/05/25 PHP