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 模块开发及发布详解分享
Mar 07 NodeJs
轻松创建nodejs服务器(5):事件处理程序
Dec 18 NodeJs
nodejs中实现路由功能
Dec 29 NodeJs
nodejs URL模块操作URL相关方法介绍
Mar 03 NodeJs
nodejs爬虫抓取数据乱码问题总结
Jul 03 NodeJs
浅谈Nodejs应用主文件index.js
Aug 28 NodeJs
nodejs 实现钉钉ISV接入的加密解密方法
Jan 16 NodeJs
NodeJs搭建本地服务器之使用手机访问的实例讲解
May 12 NodeJs
详解nodejs 配置文件处理方案
Jan 02 NodeJs
搭建一个nodejs脚手架的方法步骤
Jun 28 NodeJs
Nodejs libuv运行原理详解
Aug 21 NodeJs
nodejs制作小爬虫功能示例
Feb 24 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/06/03 PHP
PHP5.3的垃圾回收机制(动态存储分配方案)深入理解
2012/12/10 PHP
PHP isset()与empty()的使用区别详解
2017/02/10 PHP
php微信公众号开发之二级菜单
2018/10/20 PHP
随窗体滑动的小插件sticky源码
2013/06/21 Javascript
jquery鼠标停止移动事件
2013/12/21 Javascript
浅谈JavaScript中定义变量时有无var声明的区别
2014/08/18 Javascript
jQuery插件datalist实现很好看的input下拉列表
2015/07/14 Javascript
如何解决vue与传统jquery插件冲突
2017/03/20 Javascript
Vue.js 2.0学习教程之从基础到组件详解
2017/04/24 Javascript
js中字符型和数值型数字的互相转化方法(必看)
2017/04/25 Javascript
vue 验证两次输入的密码是否一致的方法示例
2020/09/29 Javascript
在IIS服务器上以CGI方式运行Python脚本的教程
2015/04/25 Python
python素数筛选法浅析
2018/03/19 Python
Python数据类型之String字符串实例详解
2019/05/08 Python
详解Selenium+PhantomJS+python简单实现爬虫的功能
2019/07/14 Python
关于pytorch多GPU训练实例与性能对比分析
2019/08/19 Python
python无序链表删除重复项的方法
2020/01/17 Python
Tensorflow实现在训练好的模型上进行测试
2020/01/20 Python
django rest framework serializers序列化实例
2020/05/13 Python
keras自定义损失函数并且模型加载的写法介绍
2020/06/15 Python
python数据抓取3种方法总结
2021/02/07 Python
css3 实现滚动条美化效果的实例代码
2021/01/06 HTML / CSS
如何整合JQuery和Prototype
2014/01/31 面试题
数控专业个人求职信范例
2013/11/29 职场文书
市场部专员岗位职责
2013/11/30 职场文书
篝火晚会策划方案
2014/05/16 职场文书
公司户外活动总结
2014/07/04 职场文书
党员批评与自我批评发言
2014/10/02 职场文书
初三英语教学反思
2016/02/15 职场文书
2016年社区党支部公开承诺书
2016/03/25 职场文书
浅谈Nginx 中的两种限流方式
2021/03/31 Servers
pytorch 一行代码查看网络参数总量的实现
2021/05/12 Python
Mybatis-plus在项目中的简单应用
2021/07/01 Java/Android
python井字棋游戏实现人机对战
2022/04/28 Python
tomcat下部署jenkins的方法
2022/05/06 Servers