美文网首页Node.js学习让前端飞程序员
深入理解 Koa 框架中间件原理

深入理解 Koa 框架中间件原理

作者: 88b61f4ab233 | 来源:发表于2018-11-27 21:18 被阅读22次

    Node 主要用在开发 Web 应用,koa 是目前 node 里最流行的 web 框架。

    在 Node 开启一个 http 服务简直易如反掌,官网 demo。

    const http = require("http");
     
    const server = http.createServer((req, res) => {
     res.statusCode = 200;
     res.setHeader("Content-Type", "text/plain");
     res.end("Hello World\n");
    });
     
    const hostname = "127.0.0.1";
    const port = 3000;
    server.listen(port, hostname, () => {
     console.log(`Server running at http://${hostname}:${port}/`);
    });
    //前端全栈学习交流圈:866109386
    //面向1-3经验年前端开发人员
    //帮助突破技术瓶颈,提升思维能力
    
    • 引入 http 模块, http 的 createServer 方法创建了一个 http.Server 的实例。
    • server 监听 3000 端口。
    • 我们传入到 createServer 里的函数实际是监听 request 事件的回调,每当请求进来,监听函数就会执行。
    • request 事件的监听函数,其函数接受两个参数,分别是 req 和 res 。其中 req 是一个可读流, res 是一个可写流。我们通过 req 获取 http 请求的所有信息,同时将数据写入到 res 来对该请求作出响应。

    koa 应用

    koa 如何创建一个 server, 直接上个官网的例子

    const Koa = require("koa");
    const app = new Koa();
     
    // x-response-time
     
    app.use(async (ctx, next) => {
     const start = Date.now();
     await next();
     const ms = Date.now() - start;
     ctx.set("X-Response-Time", `${ms}ms`);
    });
     
    // logger
     
    app.use(async (ctx, next) => {
     const start = Date.now();
     await next();
     const ms = Date.now() - start;
     console.log(`${ctx.method} ${ctx.url} - ${ms}`);
    });
     
    // response
     
    app.use(async ctx => {
     ctx.body = "Hello World";
    });
     
    app.listen(3000);
    //前端全栈学习交流圈:866109386
    //面向1-3经验年前端开发人员
    //帮助突破技术瓶颈,提升思维能力
    

    中间件概念在编程中使用广泛, 不管是前端还是后端, 在实际编程中或者框架设计都有使用到这种实用的模型。

    基本上,Koa 所有的功能都是通过中间件实现的。

    每个中间件默认接受两个参数,第一个参数是 Context 对象,第二个参数是 next 函数。只要调用 next 函数,就可以把执行权转交给下一个中间件。

    如果中间件内部没有调用 next 函数,那么执行权就不会传递下去。

    多个中间件会形成一个栈结构(middle stack),以“先进后出”(first-in-last-out)的顺序执行。整个过程就像,先是入栈,然后出栈的操作。

    上面代码的执行顺序是:

    请求 ==> x-response-time 中间件 ==> logger 中间件 ==> response中间件 ==> logger 中间件 ==> response-time 中间件 ==> 响应

    理解 Koa 的中间件机制(源码分析)

    阅读源码,化繁为简,我们看看 koa 的中间件系统是如何实现的。

    function compose(middleware) {
     return function(context, next) {
      // last called middleware #
      let index = -1;
      return dispatch(0);
      function dispatch(i) {
       if (i <= index)
        return Promise.reject(new Error("next() called multiple times"));
       index = i;
       let fn = middleware[i];
       if (i === middleware.length) fn = next;
       if (!fn) return Promise.resolve();
       try {
        return Promise.resolve(fn(context, dispatch.bind(null, i + 1)));
       } catch (err) {
        return Promise.reject(err);
       }
      }
     };
    }
    //前端全栈学习交流圈:866109386
    //面向1-3经验年前端开发人员
    //帮助突破技术瓶颈,提升思维能力
    

    我试图去简化一下这个方法,但方法本身已经足够简洁。

    代码很简洁。

    通过 next()传递 实现中间件调用, 结合 Promise 采用 递归调用 的通知机制。

    看图



    这种形式的控制流让整个 Koa 框架中间件的访问呈现出 自上而下的中间件流 + 自下而上的 response 数据流 的形式。

    Koa 本身做的工作仅仅是定制了中间件的编写规范,而不内置任何中间件。一个 web request 会通过 Koa 的中间件栈,来动态完成 response 的处理。

    koa 在中间件语法上面采用了 async + await 语法来生成 Promise 形式的程序控制流。

    相关文章

      网友评论

        本文标题:深入理解 Koa 框架中间件原理

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