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 相关文章推荐
golang、python、php、c++、c、java、Nodejs性能对比
Mar 12 NodeJs
用nodejs访问ActiveX对象,以操作Access数据库为例。
Dec 15 NodeJs
nodejs之请求路由概述
Jul 05 NodeJs
Nodejs实现的一个静态服务器实例
Dec 06 NodeJs
nodejs通过phantomjs实现下载网页
May 04 NodeJs
NodeJs——入门必看攻略
Jun 27 NodeJs
NodeJS基础API搭建服务器详细过程记录
Apr 01 NodeJs
nodejs实现爬取网站图片功能
Dec 14 NodeJs
详解从NodeJS搭建中间层再谈前后端分离
Nov 13 NodeJs
Nodejs实现的操作MongoDB数据库功能完整示例
Feb 02 NodeJs
nodejs中各种加密算法的实现详解
Jul 11 NodeJs
Nodejs技巧之Exceljs表格操作用法示例
Nov 06 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/06 日漫
php版微信支付api.mch.weixin.qq.com域名解析慢原因与解决方法
2016/10/12 PHP
纯CSS3实现质感细腻丝滑按钮
2021/03/09 HTML / CSS
js iframe跨域访问(同主域/非同主域)分别深入介绍
2013/01/24 Javascript
简单的Jquery全选功能
2013/11/07 Javascript
深入理解JavaScript系列(45):代码复用模式(避免篇)详解
2015/03/04 Javascript
深入分析Javascript跨域问题
2015/04/17 Javascript
快速学习jQuery插件 Cookie插件使用方法
2015/12/01 Javascript
全面解析jQuery $(document).ready()和JavaScript onload事件
2016/06/08 Javascript
JS简单实现DIV相对于浏览器固定位置不变的方法
2016/06/17 Javascript
Vue.js中用v-bind绑定class的注意事项
2016/12/13 Javascript
详解jQuery事件
2017/01/13 Javascript
JavaScript DOM节点操作实例小结(新建,删除HTML元素)
2017/01/19 Javascript
利用n 升级工具升级Node.js版本及在mac环境下的坑
2017/02/15 Javascript
Vue.js实现开发购物车功能的方法详解
2019/02/22 Javascript
vue中el-input绑定键盘按键(按键修饰符)
2020/07/22 Javascript
python实现巡检系统(solaris)示例
2014/04/02 Python
简单介绍Python中的struct模块
2015/04/28 Python
python 远程统计文件代码分享
2015/05/14 Python
Python错误处理操作示例
2018/07/18 Python
Python网络爬虫之爬取微博热搜
2019/04/18 Python
浅谈Pytorch中的自动求导函数backward()所需参数的含义
2020/02/29 Python
使用keras实现非线性回归(两种加激活函数的方式)
2020/07/05 Python
HTML5实现可缩放时钟代码
2017/08/28 HTML / CSS
美津浓巴西官方网站:Mizuno巴西
2019/07/24 全球购物
意大利香水和化妆品购物网站:Parfimo.it
2019/10/06 全球购物
德国最大的婴儿用品网上商店:Kidsroom.de(支持中文)
2020/09/02 全球购物
FirstCry阿联酋儿童和婴儿产品网上购物:FirstCry.ae
2021/02/22 全球购物
公司庆典邀请函范文
2014/01/13 职场文书
新品发布会主持词
2014/04/02 职场文书
个人房屋买卖协议书(范本)
2014/10/04 职场文书
计划生育工作汇报
2014/10/28 职场文书
培训心得体会怎么写
2016/01/25 职场文书
python关于集合的知识案例详解
2021/05/30 Python
springboot拦截器无法注入redisTemplate的解决方法
2021/06/27 Java/Android
Python中的嵌套循环详情
2022/03/23 Python