前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >express框架route.js源码解析

express框架route.js源码解析

作者头像
theanarkh
发布2019-03-06 10:27:04
6390
发布2019-03-06 10:27:04
举报
文章被收录于专栏:原创分享原创分享

route.js并不是express里真正的路由代码,他只是其中的一个组成部分,和router(router/index.js)是有区别的。下面先看一下重要的代码。

代码语言:javascript
复制
function Route(path) {
  this.path = path;
  this.stack = [];
  // route handlers for various http methods
  this.methods = {};
}

Route.prototype.dispatch = function dispatch(req, res, done) {//done是router的next函数,执行后会跳到下一个中间件,从而跳过当前route的stack中剩下的函数
  var idx = 0;
  var stack = this.stack;
  if (stack.length === 0) { 
    return done();//done是开始执行该路由组件时传进来的回调,执行完路由栈里的函数后执行done
  }

  var method = req.method.toLowerCase();
  if (method === 'head' && !this.methods['head']) {
    method = 'get';
  }

  req.route = this;

  next();

  function next(err) {
    if (err && err === 'route') {//使用next('route')会不执行剩下的函数
      return done();
    }

    var layer = stack[idx++];
    if (!layer) {//已经遍历完layer了,跳到下一个router中的layer
      return done(err);
    }

    if (layer.method && layer.method !== method) {//方法不匹配,next
      return next(err);
    }

    if (err) {//通过层层筛选,最后可以执行的路由函数,先判断有没有错误,再执行相应的函数,每个layer都有对应的回调。
      layer.handle_error(err, req, res, next);
    } else {
      layer.handle_request(req, res, next);
    }
  }
};

Route.prototype.all = function all() {
  var handles = flatten(slice.call(arguments));

  for (var i = 0; i < handles.length; i++) {
    var handle = handles[i];

    if (typeof handle !== 'function') {
      var type = toString.call(handle);
      var msg = 'Route.all() requires callback functions but got a ' + type;
      throw new TypeError(msg);
    }

    var layer = Layer('/', {}, handle);
    layer.method = undefined;

    this.methods._all = true;
    this.stack.push(layer);
  }

  return this;
};
代码语言:javascript
复制

首先route是作为一个layer对象的一个属性,挂在在layer中的,route本身的结果类似于router,是一个数组,或者说是一个栈。元素的类型是layer。 1.构造函数比较简单,主要是存储路由的路径和分配一个数组存储layer数据结构。methods的存在主要是因为前端请求一个路径,可以对应很多种http方法,比如get,post这种,所以methods变量主要是用在匹配路由时进行筛选时。 2.各种http方法和一个特殊的all方法的逻辑是类似的,主要是根据传进来的0个或者多个回调函数,创建0个或者多个layer层,并且把他们加到route的数组中。 3.dispatch是最重要的函数,这个函数是在路由查找的过程中,匹配到了当前的路由时执行。核心的逻辑在next函数里,并且这个next函数和router里的next是不一样的。代码的第一行先判断执行next的时候,是否传入了route,是的话,就忽略当前栈中还没有执行的函数,跳到下一个路由层。我们可以想象express的整个路由机制有点类似二维数组,比如是5*5的,我们先在一维数组里查找路由(router的逻辑),找到后,假设是第二行,然后我们执行第二行里的所有列对应的函数(route的逻辑)。回到上面,假设是在第二列next到第三列时,执行next的时候传入了route,那么第三列和后面的函数都不会被执行,路由机制会继续从第三行往后找匹配的路径。这里是通过执行done达到这个效果。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-02-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 编程杂技 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档