内容简介:Node 主要用在开发 Web 应用,koa 是目前 node 里最流行的 web 框架。在 Node 开启一个 http 服务简直易如反掌,官网 demo。
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}/`); }); 复制代码
- 引入
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); 复制代码
中间件概念在编程中使用广泛, 不管是前端还是后端, 在实际编程中或者框架设计都有使用到这种实用的模型。
基本上,Koa 所有的功能都是通过中间件实现的。
每个中间件默认接受两个参数,第一个参数是 Context
对象,第二个参数是 next
函数。只要调用 next
函数,就可以把执行权转交给下一个中间件。
如果中间件内部没有调用 next
函数,那么执行权就不会传递下去。
多个中间件会形成一个栈结构(middle stack),以“先进后出”(first-in-last-out)的顺序执行。整个过程就像,先是入栈,然后出栈的操作。
上面代码的执行顺序是:
请求 ==> x-response-time 中间件 ==> logger 中间件 ==> response中间件 ==> logger 中间件 ==> response-time 中间件 ==> 响应 复制代码
理解 Koa 的中间件机制(源码分析)
阅读源码,化繁为简,我们看看 koa 的中间件系统是如何实现的。
class Application extends Emitter { constructor() { super(); this.middleware = []; }, use(fn) { this.middleware.push(fn); return this; }, callback() { const fn = compose(this.middleware); return function(req, res) { return fn(ctx); }; }, listen(...args) { const server = http.createServer(this.callback()); return server.listen(...args); } } 复制代码
好了,精简结束,一不小心,去枝末节,最后只剩下不到 20 行代码。
这就是框架的核心,简化后的代码非常清晰,有点不可思议,但核心就是这么简单。
我们先分析以上代码做了什么事。
-
我们定义了一个
middleware
数组来存储中间件。 -
我们定一个了一个
use
方法来注册一个中间件。其实就是简单的push
到自身的mideware
这个数组中。 -
我们还使用了一个
compose
方法,传入middleware
,应该是做了一些处理,返回了一个可执行的方法。
你一定对中间的 compose
方法很好奇,初此之外的代码都容易理解,唯独这个 compose
不太知道究竟做了什么。
其实, compose
就是整个中间件框架的核心。
compose
之外,代码已经很清楚的定义了
-
中间件的存储
-
中间件的注册
而 compose
方法做了最为重要的一件事
- 中间件的执行
核心源码 compose
先上码
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); } } }; } 复制代码
我试图去简化一下这个方法,但方法本身已经足够简洁。
代码很简洁。
通过 next()传递
实现中间件调用, 结合 Promise
采用 递归调用 的通知机制。
看图
这种形式的控制流让整个 Koa 框架中间件的访问呈现出 自上而下的中间件流
+ 自下而上的 response 数据流
的形式。
Koa 本身做的工作仅仅是定制了中间件的编写规范,而不内置任何中间件。一个 web request
会通过 Koa 的中间件栈,来动态完成 response
的处理。
koa 在中间件语法上面采用了 async
+ await
语法来生成 Promise
形式的程序控制流。
总结
koa 是非常精简的框架, 其中的精粹思想就是洋葱模型(中间件模型), koa 框架的中间件模型非常好用并且简洁, 但是也有自身的缺陷, 一旦中间件数组过于庞大, 性能会有所下降,我们需要结合自身的情况与业务场景作出最合适的选择.
以上所述就是小编给大家介绍的《理解 Koa 框架中间件原理》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 中间件增强框架之InterceptFramework
- golang框架gin中间件的写法
- Koa框架实践与中间件原理剖析
- 【02-中间件】构建go web框架
- Gin 框架系列(三):换个姿势理解中间件
- Gin框架系列03:换个姿势理解中间件
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。