从源码分析express中间件和路由添加方式的区别

总览:

* 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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值