美文网首页实用前端
Express中间件的原理及实现

Express中间件的原理及实现

作者: waka | 来源:发表于2017-03-06 18:51 被阅读2606次

参考文章:初学nodejs一:别被Express的API搞晕了

GitHub,欢迎star:https://github.com/BadWaka/node-express-middleware-study

在Node开发中免不了要使用框架,比如expresskoakoa2

拿使用的最多的express来举例子

开发中肯定会用到很多类似于下面的这种代码

var express = require('express');
var app = express();
app.listen(3000, function () {
    console.log('listen 3000...');
});

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

对我要说的就是app.use()

为什么要说这个?因为面试时被问到了。。。

哦 你用过Express啊 来来来 那你说说app.use的原理是什么?

一脸懵逼...0.0

app.use()就是通常所说的使用中间件

那中间件是什么呢?它又有啥用呢?

中间件 middleware

一个请求发送到服务器后,它的生命周期是 先收到request(请求),然后服务端处理,处理完了以后发送response(响应)回去

而这个服务端处理的过程就有文章可做了,想象一下当业务逻辑复杂的时候,为了明确和便于维护,需要把处理的事情分一下,分配成几个部分来做,而每个部分就是一个中间件

node.js - express 框架中的app.use是什么作用? - SegmentFault

app.use 加载用于处理http请求的middleware(中间件),当一个请求来的时候,会依次被这些 middlewares处理。

中间件执行的顺序是你定义的顺序

那中间件到底是个什么东西呢?

中间件其是一个函数,在响应发送之前对请求进行一些操作

function middleware(req,res,next){
    // 做该干的事

    // 做完后调用下一个函数
    next();
}

这个函数有些不太一样,它还有一个next参数,而这个next也是一个函数,它表示函数数组中的下一个函数

那函数数组又是什么呢

express内部维护一个函数数组,这个函数数组表示在发出响应之前要执行的所有函数,也就是中间件数组

使用app.use(fn)后,传进来的fn就会被扔到这个数组里,执行完毕后调用next()方法执行函数数组里的下一个函数,如果没有调用next()的话,就不会调用下一个函数了,也就是说调用就会被终止

Express中间件的使用

理论部分简单的说了一下,现在来用代码验证一下,注意需要安装一下express

/**
 * express中间件的实现和执行顺序
 *
 * Created by BadWaka on 2017/3/6.
 */
var express = require('express');

var app = express();
app.listen(3000, function () {
    console.log('listen 3000...');
});

function middlewareA(req, res, next) {
    console.log('middlewareA before next()');
    next();
    console.log('middlewareA after next()');
}

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

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

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

输出结果:


可以看到在执行完下一个函数后又会回到之前的函数执行next()之后的部分
这可以理解为中间件的一个特性吧

现在可以说已经明白Express的中间件是什么了,以及app.use的用法了,下面就来自己实现一下吧

实现简单的Express中间件

/**
 * 仿照express实现中间件的功能
 *
 * Created by BadWaka on 2017/3/6.
 */

var http = require('http');

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

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

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

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

        next();
    }

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

    return app;    // 返回实例
}

// 下面是测试case

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

function middlewareA(req, res, next) {
    console.log('middlewareA before next()');
    next();
    console.log('middlewareA after next()');
}

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

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

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

JS是一门神奇的语言,这里用到了两个闭包,并且给app这个函数添加了一个use方法,函数也是可以有属性的

原理就是每调用一次use,就把传进来的函数扔到express内部维护的一个函数数组中去

测试结果:


ok,相信对Express中间件的原理已经有所了解了,koa和koa2中间件的原理其实也是一样的

继续去看源码了。。。

相关文章

  • express中间件原理及实现

    中间件是一种拦截器的思想,用于在某个特定的输入输出之间添加一些额外的处理,它最大的特点就是,一个中间件处理完,再传...

  • Express中间件的原理及实现

    参考文章:初学nodejs一:别被Express的API搞晕了 GitHub,欢迎star:https://git...

  • Express中间件的原理及实现

    中间件 middleware一个请求发送到服务器后,它的生命周期是 先收到request(请求),然后服务端处理,...

  • 简单实现node中间件机制-仿express

    express中间件机制原理 首先,我们看一下express使用是怎么使用中间件的。 其实app.use()原理很...

  • express中间件理解

    express中间件原理及实现——初体验 之前看node大概了解了一些基本代码段,最近重新拿起来学习,就先了解了一...

  • 重写express

    模拟express 的实现原理* use()添加到 md 的中间件函数。 把路由部分routers,在函数rout...

  • nodejs之中间件框架Connect源码浅谈

    前言 上篇文章介绍了express中间件的使用和如何自己实现中间件,也介绍了其实express中间件的实现依赖了C...

  • nodejs之koa中间件源码解析

    前言 上一篇《nodejs之express中间件》已经对express中间件的实现做了详细的讲解,同时也对实现中间...

  • 跟我一起学Express之session、redis、登录验证

    上节我们说到,express中间件,并简单实现了我们自己的中间件,按照小编自己的理解 express就是靠中间件为...

  • express middleware的使用

    更新中~ express 中间件 中间件的作用一般是为了实现业务的解耦,提供访问的接口。在express中,中间件...

网友评论

  • 8edf00dfcb72:啥面试这么简单。。
    koa是es6的class来写
    koa2基于的也是async/await异步调用,而他们就是不同的js线程的东西
    7adbe2f4efde:@王者荣耀1V1 koa核心是generator 哪来的什么class 当然楼上那个说的也不对 async/await是generator的语法糖,只是返回的是promise对象,而且js执行栈本来就只有一条,你要谈事件循环和js解释执行本身没什么太大关系,那是js执行环境提供的一个异步实现策略在js执行栈空的时候推入相应的上下文,你说他是不同js线程这本身就是个问题,而且我也不知道你说的这个‘他们’指代的是哪些
    8edf00dfcb72:@lean_ node的事件循环模型有了解???
    lean_:async/await不是基于promise的语法糖吗?怎么变成不同线程了。 nodejs也是单线程的吧?
  • Jarone:简单易懂,:+1:

本文标题:Express中间件的原理及实现

本文链接:https://www.haomeiwen.com/subject/zhuugttx.html