express实现原理

面试经常会问到一些原理性的东西,比如express,知道你会用,但可能就会问你实现的原理是什么,废话不多说。

express的所有服务端逻辑处理都是通过中间件来实现的,中间件是一个函数,而app.use()方法就是去装载这些函数,并放入一个数组中。

当前端一个请求传到服务器的时候,首先会经过request,然后是一系列的服务端处理,也就是中间件处理,存放于数组中的中间件采用后进先出的栈模式处理请求,最先入栈的中间件处理完请求之后,通过next将执行权交给第二个入栈的中间件,依次类推,直到数组末尾或者中间某个中间件没有调用next()函数,最后再将处理完的结果response回前端。

接下来让我们自己来简单实现一下:

/**
 * 仿照express实现中间件的功能
 *
 * Created by haoxin on 2018/7/9.
 */

var http = require('http');

/**
 * 仿express实现中间件机制
 *
 * @return {app}
 */
var express = () => {

    var funcs = []; // 待执行的函数数组

    var app = (req, res) => {
        var i = 0;

        var next = () => {
            var task = funcs[i++];  // 取出函数数组里的下一个函数
            if (!task) {    // 如果函数不存在,return
                return;
            }
            task(req, res, next);   // 否则,执行下一个函数
        }

        next();
    }

    /**
     * use方法就是把函数添加到函数数组中
     * @param task
     */
    app.use = (task) => {
        funcs.push(task);
    }

    return app;    // 返回实例
}

// 下面是测试case

var app = express();
http.createServer(app).listen('3000', () => {
    console.log('listening 3000....');
});

const middlewareA = (req, res, next) => {
    if(req.url!=="/favicon.ico") {  //防止重复请求
        console.log('middlewareA before next()');
        next();
        console.log('middlewareA after next()');
    }
    res.end();
}

const middlewareB = (req, res, next) => {
    console.log('middlewareB before next()');
    next();
    console.log('middlewareB after next()');
}

const middlewareC = (req, res, next) => {
    console.log('middlewareC before next()');
    next();
    console.log('middlewareC after next()');
}

app.use(middlewareA);
app.use(middlewareB);
app.use(middlewareC);

打开命令行,切换到该文件目录下,执行


看到输出结果:


好了,接下来看看源码中的实现方式,直接上图:

首先是文件:node_modules/express/lib/application.js




然后是:node_modules/express/lib/router/route.js


然后是:node_modules/express/lib/router/index.js




参考:https://www.jianshu.com/p/797a4e38fe77


猜你喜欢

转载自blog.csdn.net/ppx2017/article/details/80967690