总览:
* app.use(),app.get()添加的中间件在一个router实例中的stack栈中
* app.get()在router中的layer中又创建了一个Route实例,Route实例中的stack栈中又存放了一个layer中间层
* app.Router().get()添加的中间件在另外一个router实例中
* app.Router生成一个实例,app.Router().get()每次创建的中间件在这个实例的stack栈中
express中间件添加时可以使用app.use,也可以使用app.get(),app.post()或者app.route(), app.Router().get(),app.Router().post()等,这些方式有什么区别呢,接下来熊源码执行上区分一下这些方法。
app.use()最终会执行以下代码:
for (var i = 0; i < callbacks.length; i++) {
var fn = callbacks[i];
if (typeof fn !== 'function') {
throw new TypeError('Router.use() requires a middleware function but got a ' + gettype(fn))
}
// add the middleware
debug('use %o %s', path, fn.name || '<anonymous>')
var layer = new Layer(path, {
sensitive: this.caseSensitive,
strict: false,
end: false
}, fn);
layer.route = undefined;
this.stack.push(layer);
}
可以看出,
1,use方法创建的中间件layer属性:strict=false, end =false, route=undefined,path=path
2,layer中间件存储在router实例的stack栈中;
app.route(path)执行逻辑:只接受一个参数path
app.route = function route(path) {
this.lazyrouter();
return this._router.route(path);
};
proto.route = function route(path) {
var route = new Route(path);
var layer = new Layer(path, {
sensitive: this.caseSensitive,
strict: this.strict,
end: true
}, route.dispatch.bind(route));
layer.route = route;
this.stack.push(layer);
return route;
};
从上面代码可以看出app.route()返回的是一个route对象,并把这个对象放入this._router实例中
————————————————————————————————————————————
对于除了use,app.route方法之外的方法,例如get, post, put等等,执行逻辑如下:
对于,app.get('/',function(req,res,next){})类似的方式,先在application中执行:
methods.forEach(function(method){
app[method] = function(path){
if (method === 'get' && arguments.length === 1) {
// app.get(setting)
return this.set(path);
}
this.lazyrouter();
var route = this._router.route(path); //去执行route实例的route方法
route[method].apply(route, slice.call(arguments, 1));
return this;
};
});
app.Router().get()这一类方式,先在router中执行:
methods.concat('all').forEach(function(method){
proto[method] = function(path){
var route = this.route(path)
route[method].apply(route, slice.call(arguments, 1));
return this;
};
});
接下来,app.get(),app.Router().get()这两类方式执行逻辑一样,在router中执行:
proto.route = function route(path) {
var route = new Route(path);
var layer = new Layer(path, {
sensitive: this.caseSensitive,
strict: this.strict,
end: true
}, route.dispatch.bind(route));
layer.route = route;
this.stack.push(layer);
return route;
};
从代码中可以看出使用use添加中间件的区别:
1,先创建了一个Route实例
2,get等方法创建的layer属性:strict=this.strict, end = true, route=Route实例,path=path
3,layer中间层放入this.stack栈中
4,app.get存入的router实例和router存入的实例不是一个
总结:use方法和get等其他方法的区别主要是创建的layer中间层的route属性有没有值,也就是有没有路由。
一般的,use主要用于添加中间件,而get等用于添加路由对应的处理事件。
参考:https://cloud.tencent.com/developer/section/1489347#stage-100050992