express初识源码-Router,Layer,Route

express提供丰富的http工具,快速处理请求,响应。核心功能中间件,路由,基于三个类来实现,Router,Layer,Route。

1.Router

主要核心内容:

  • stack数组存放子路由,中间件。
  • handle方法,循环stack数组,根据规则执行响应回调函数。
image

一般添加一个路由会这样写代码:

    app.get('/list', function (req, res) {
        res.end('hello express');
    });

在Router里面做了一件事来支持这样的写法:


    var methods = require('methods');  //包含http的方法名
    
    methods.forEach((methods) => {
        //拿到具体一个方法名 methods
        Router.prototype[methods] = function() {
            // 调用route方法往stack里面push一个路由
        }
    })

express中路由和中间件都是放在了stack数组里面,那么就有顺序问题,如果use一个中间件那么需要放在路由前面。

    const express = require('express');
    const app = new express();
    
    app.use((req, res, next) => {
        console.log('111');
        next();
    });
    
    app.get('/list',(req, res) => {
        res.end('hello express');  
    });
    
    app.listen('8000');

next表示通过,可以执行下个中间件或路由,如果发生错误,则可以抛出错误,交给错误中间件处理,错误中间件接受4个参数,4个参数的use就代表了错误中间件.第一个参数为错误信息

    app.use((req, res, next) => {
        console.log('111');
        next(new Error('error'));
    });
    
    app.use((error, req, res, next) => {
        console.log(error);
    })

当请求来时,会执行handle,循环stack,发现path相同,method相同,那么调用对应callback。这样处理,带来了一个问题,如果路由不断增多,stack数组会不断增大,匹配效率下降,为了提高效率,express引入了route,layer.

2.Layer

把同一个path形成一层,并提供match方法进行匹配判断,handle方法来执行当前层的深入匹配methods。

简单理解就是匹配一个路径,然后执行回调方法。

那么当一个路由注册的时候,则新生成一个Layer实例,如果剩下还有路由路径相同,则放在该层。怎么去放入这层的,在Route做。

3.Route

image

Layer形成了层,但没有做匹配methods的事情,那么这个事情由Route来做。在Layer里面会传入一个handle方法,那么这个handle方式就是Route里面的dipatch方法,当Layer的路径已经匹配成功,就会交给Route来匹配method,Route的对象存放所有注册的方法名,用于快速匹配是否有注册该方法,在Route里面又复用了Layer,去执行真正回调处理函数。

4.实现高效率匹配

    app.route('/list').get((req, res) => {
        res.end('hello get');  
    }).post((req, res) => {
        res.end('hello post');  
    }).put((req, res) => {
        res.end('hello put');
    }).delete((req, res) => {
        res.end('hello delete');
    });

下面看一个伪代码,看如何去实现的app.route方法:

    app.route = function(path) {
        const route = new Route(path); // 生成一个route实例
        const Layer = new Layer(path, route.dispatch.bind(route)); // 把route里面的dispatch方法作为Layer的处理函数
        
        this.stack.push(layer); // 放入数组中
        
        return route; // 返回route实例,用于链式调用,去注册method方法
    }
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容