Express app.listen 函数了解
2016-05-21 22:43
501 查看
最近一直在学习如何用原生的 Node.js 来做一个网站。在写的同时也在学习 Express 源码。
一直觉得 Express 开启服务器的方法挺有趣的,就看了一下。
在 Express 运行的时候会默认运行根目录下的 index.js,里面的源码也很简单:
看到其实运行了
导出了
首先定义了一个方法
再往下看看,会看到
看源码,如果对原生JS的函数不是很熟悉的话,根本看不懂...不过我们可以到
由此可见:
这两句话就很好懂了,就是将
这里看到
额...又是一个模块,继续追踪,第一句话:
唉哟,又看到了
这里我们找到我们希望看到的一个
好烦哟...又碰到看不懂的了,尼玛
好吧,没办法,我们
第一句居然是
哎哟,不错哟,貌似发现了新大陆...明明在
这句话,好像很突然的想到似的...是否在想明明在
在 CMD 或者 终端 执行:node app
在我们自己写的
进去
从
在
在
然后通过
执行
继续执行
最后返回
在我们自己写的
开始执行
这么晚写这文章,感觉写了一大坨废话...最后的执行顺序才是我最想说的
一直觉得 Express 开启服务器的方法挺有趣的,就看了一下。
在 Express 运行的时候会默认运行根目录下的 index.js,里面的源码也很简单:
module.exports = require('./lib/express');
看到其实运行了
lib/express模块,追踪过去,看到了:
exports = module.exports = createApplication;
导出了
createApplication这个方法:
function createApplication() { var app = function(req, res, next) { app.handle(req, res, next); }; mixin(app, EventEmitter.prototype, false); mixin(app, proto, false); app.request = { __proto__: req, app: app }; app.response = { __proto__: res, app: app }; app.init(); return app; }
首先定义了一个方法
app,方法有三个参数
req,
res,
next。然后在这个函数里面又执行了
app.handle这个函数,这个函数后面说说,涉及到了路由。同时还涉及到了创建服务器函数,下面继续。
再往下看看,会看到
mixin这个函数,在最上面引入模块的时候,定义了这个函数名:
var EventEmitter = require('events').EventEmitter; var mixin = require('merge-descriptors'); var proto = require('./application'); var Route = require('./router/route'); var Router = require('./router'); var req = require('./request'); var res = require('./response');
mixin这个函数是引用了
merge-descriptors模块,嗯,到
node_module里面找找,或者到
github里面找找也可以。
看源码,如果对原生JS的函数不是很熟悉的话,根本看不懂...不过我们可以到
MDN里面查查,地址懒的贴。我也懒得去介绍里面的各种函数,这个模块的作用和
jQuery里面的
$.extent其实是一模一样的,将第二个参数的属性和属性值合并到第一个参数中,第三个参数如果是
false则如果两个参数里面有属性一样,不允许覆盖,如果是
true,则覆盖第一个参数属性。
由此可见:
mixin(app, EventEmitter.prototype, false); mixin(app, proto, false);
这两句话就很好懂了,就是将
EventEmitter.prototype和
proto的属性克隆给
app。
这里看到
proto肯定也很郁闷...这玩意从哪里来的...还是往上面看:
var proto = require('./application');
额...又是一个模块,继续追踪,第一句话:
var app = exports = module.exports = {};
唉哟,又看到了
app,这
express命名也是有趣,都是
app。我再看的时候也很郁闷,完全会看混淆。继续往下看,原来这个模块的作用就是给
app添加了各种属性和函数,各种核心函数...各种看不懂的函数...
这里我们找到我们希望看到的一个
listen这个函数:
app.listen = function listen() { var server = http.createServer(this); return server.listen.apply(server, arguments); };
好烦哟...又碰到看不懂的了,尼玛
this是什么鬼!!!!我们从 Node.js 的 API 手册可以看到啊,明明官方都说了:
The requestListener is a function which is automatically added to the 'request' event.
this这个参数的位置明明应该是一个函数啊,但是在
application里面我们看到的
app很显然就是一个
{}对象啊,尼玛,怎么可能是一个
Function?
好吧,没办法,我们
console.log(this)试试,看看返回的是什么:
{ [Function] domain: undefined, _events: { mount: [Function: onmount] }, _maxListeners: undefined, setMaxListeners: [Function: setMaxListeners], getMaxListeners: [Function: getMaxListeners], emit: [Function: emit], addListener: [Function: addListener], on: [Function: addListener], once: [Function: once], removeListener: [Function: removeListener], removeAllListeners: [Function: removeAllListeners], listeners: [Function: listeners], listenerCount: [Function: listenerCount], init: [Function: init], defaultConfiguration: [Function: defaultConfiguration], lazyrouter: [Function: lazyrouter], handle: [Function: handle], use: [Function: use], route: [Function: route], ...
第一句居然是
Function,是什么鬼?什么时候变成了
Function,仔细看一下,我们发现里面好像有
EventEmitter.prototype的属性:
EventEmitter { domain: undefined, _events: undefined, _maxListeners: undefined, setMaxListeners: [Function: setMaxListeners], getMaxListeners: [Function: getMaxListeners], emit: [Function: emit], addListener: [Function: addListener], on: [Function: addListener], once: [Function: once], removeListener: [Function: removeListener], removeAllListeners: [Function: removeAllListeners], listeners: [Function: listeners], listenerCount: [Function: listenerCount] }
哎哟,不错哟,貌似发现了新大陆...明明在
application这个模块没有添加这个属性啊,从哪里加的?这个时候我们应该顺其自然的想到了:
mixin(app, EventEmitter.prototype, false);
这句话,好像很突然的想到似的...是否在想明明在
express这个模块加的,为啥在
application里面会添加进去?OK,到了我们最关键的时候了,我们应该把
Express的执行顺序理清楚了:
在 CMD 或者 终端 执行:node app
在我们自己写的
app.js文件中执行
express(),这里就开始运行
express模块了。
进去
express模块,运行
index.js
从
index.js进去
lib/express.js
在
express.js中执行
createApplication
在
createApplication中首先定义了一个
app的函数,其实刚才我们
console.log(this)的时候,
this返回的就是这个
app函数
然后通过
mixin(app, EventEmitter.prototype, false);mixin(app, proto, false);将
EventEmitter.prototype、
proto里面的属性全部都加到
app这个函数里面
执行
app.request、
app.response这两个就是将重新定义的
request、
response加到
app里面,这两个以后再说
继续执行
app.init();,这句话就简单了啊,
init这个函数在
application.js模块中,主要作用就是给
app加一些初始化设置
最后返回
app
在我们自己写的
app.js文件中获取到返回的
app,准备创建服务器
app.listen(3000)
开始执行
app.listen这个函数,在
app中找到
listen,这个函数在
express.js中已经从
proto克隆到了
app上了,所以,我们直接到
proto中找
listen,也就是
application.js中去找,找到之后就回到了我们最开始的问题:
var server = http.createServer(this);,
this是什么????看到这里,其实我们已经知道了,
this其实就是
var app = function(req,res,next){},OK到这里就结束了...
这么晚写这文章,感觉写了一大坨废话...最后的执行顺序才是我最想说的
相关文章推荐
- Android 将高德定位分离出来
- AndroidStudio初始化配置
- Android ListView IndexOutOfBoundsException ViewHolder类型转化错误
- Android系统自带样式(@android:style/)
- android wifi断开原因分析
- ionic android 发布
- Unity3D 之UGUI 文本框和编辑框
- Android PowerManagerService和PowerManager 源码分析
- Cocos2dx游戏引擎(3.x)----新的事件分发机制
- iOS 生命周期 -init、viewDidLoad、viewWillAppear、viewDidAppear、viewWillDisappear、viewDidDisappear 区别和用途
- Android开发:ListView、AdapterView、RecyclerView全面解析
- 作业——在线学习Android课程之第十二周(内存优化)
- Android 使用DownloadManager进行版本更新的完整方案
- Android 使用DownloadManager进行版本更新的完整方案
- Android随笔小记 Permission
- Unity4.3 遮挡剔除:基本知识
- [置顶] Android 属性动画详解
- Error:Cause: failed to find target with hash string 'android-15'
- Android中Toast的用法简介
- Android拼图游戏