nodejs模块学习之connect解析

2020-06-17 06:38:57易采站长站整理

function handle () {
function app(req, res, next) { app.handle(req, res, next)}
app.handle = function (req, res, next) {

console.log( this );

}
app.statck = [];
return app;

}
var app = handle();
app() // ==> { [Function: app] handle: [Function], stack: [] }
app.apply({}) // ==>{ [Function: app] handle: [Function], stack: [] }

可以看出:函数中的实例函数中的 this 就是指当前的实例,不会因为你使用 apply 进行环境改变。

其他就跟对象没有什么区别。

再次回到示例代码,因该可以看懂了,  connect  方法返回了一个函数,这个函数能直接调用,有 use 方法,用来响应 http 的 request 事件。

到此为此,示例代码就讲完了。 我们开始进入到 connect 模块的内部。

connect 只有一个导出方法。就是如下:


var merge = require( 'utils-merge' );

module.exports = createServer;

var proto = {};

function createServer() {

// 函数对象,这个对象能调用,能加属性

function app(req, res, next){ app.handle(req, res, next); }

merge(app, proto); // ===等于调用 Object.assign

merge(app, EventEmitter.prototype); // === 等于调用 Object.assign

app.route = '/' ;

app.stack = [];

return app;

}

从代码中可以看出,createServer 函数把 app 函数返回了,app 函数有三个参数,多了一个 next (这个后面讲),app函数把 proto 的方法合并了。还有 EventEmitter 的方法也合并了,还增加了 route 和 stack 的属性。

从前面代码来看,响应 request 的事件的函数,是 app.handle 方法。这个方法如下:


proto.handle = function handle(req, res, out) {

var index = 0;

var protohost = getProtohost(req.url) || '' ; //获得 http://www.baidu.com

var removed = '' ;

var slashAdded = false ;

var stack = this .stack;

// final function handler

var done = out || finalhandler(req, res, {

env: env,

onerror: logerror

}); // 接口 done(err);

// store the original URL

req.originalUrl = req.originalUrl || req.url;

function next(err) {

if (slashAdded) {

req.url = req.url.substr(1); // 除掉 / 之后的字符串

slashAdded = false ; // 已经拿掉

}

if (removed.length !== 0) {

req.url = protohost + removed + req.url.substr(protohost.length);

removed = '' ;

}

// next callback

var layer = stack[index++];

// all done

if (!layer) {

defer(done, err); // 没有中间件,调用 finalhandler 进行处理,如果 err 有值,就返回 404 进行处理