zoukankan      html  css  js  c++  java
  • Express中间件的原理及实现

    在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中间件的原理其实也是一样的




    转自:https://www.jianshu.com/p/797a4e38fe77

  • 相关阅读:
    欧拉回路 定理
    UESTC 1087 【二分查找】
    POJ 3159 【朴素的差分约束】
    ZOJ 1232 【灵活运用FLOYD】 【图DP】
    POJ 3013 【需要一点点思维...】【乘法分配率】
    POJ 2502 【思维是朴素的最短路 卡输入和建图】
    POJ 2240 【这题貌似可以直接FLOYD 屌丝用SPFA通过枚举找正权值环 顺便学了下map】
    POJ 1860【求解是否存在权值为正的环 屌丝做的第一道权值需要计算的题 想喊一声SPFA万岁】
    POJ 1797 【一种叫做最大生成树的很有趣的贪心】【也可以用dij的变形思想~】
    js 实现slider封装
  • 原文地址:https://www.cnblogs.com/donve/p/10265326.html
Copyright © 2011-2022 走看看