最近有用到 Express 以及 Koa 做一些 Mock Server 以及开发平台的搭建工作,这篇文章会把 Koa 常用方法的流程源码梳理一下,用到的 Koa 版本是 2.7.0 。
文件结构
在项目依赖了 Koa 后,可以从 node_modules 中找到 koa 文件夹,文件结构大概如下:
koa-files可以看到其相关源文件只有四个, application 应用, context 上下文, request 以及 response 的封装。
Koa 实例创建, 监听端口及回调函数
koa-start如图所示这里我们创建了一个 Koa 实例,然后简单的返回了内容并开始监听 6060 端口,下面则是 Koa 实例的 constructor
代码:
一些初始化工作:
~ 初始化中间件数组
~ 读取环境参数
~ 初始化 context, request, response 对象
另外我们可以看到 Koa Application 继承自 Node.js 的 Emitter 类,来继承事件触发以及事件监听的能力。
koa-listenlisten
方法则只是对 http 模块方法的调用,只不过把回调函数 handle 到自己这里。
use
方法先是类型检查,也附带对函数是不是 Generator Function 进行了检查,Koa v3 后则不再支持 generators ,取而代之推荐使用 async/await
。 之后则是直接把传入的函数 push 进中间件数组,支持链式调用,返回 this 。
再来看看作为回调处理传给 http 创建时候的 callback 方法
compose 函数把所有 middleware 结合到一起, 然后创建一个函数常量,内部会创建一个上下文对象提供给每个 middleware 获取 request, response 以及其他信息。
下面会详细介绍 middleware 处理流程以及 context 对象。
Middleware
Koa 是一个相对轻量级的库,这个 compose 方法在一个 koa-compose 的包中,这个包也只有这一个方法的实现:
koa-compose上来是参数对象以及数组中的对象类型校验,然后 call 了内部方法 dispatch ,每一个 fn 调用时都通过 Promise 来支持异步,从第一个索引一直调用到最后,因为每一个中间件都能获取到 context 以及 next 函数,所以在最后 resovle 中是调用 fn(context, dispatch.bind(null, i+1))
另外因为中间件拥有足够的自由度来决定什么时候执行 next 函数,所以 middleware 执行中间件的流程大概如图所示
koa-middlewareContext
上面提到过,在回调方法内会先创建一个上下文对象:
koa-create-context这个方法比较简单,大部分为赋值操作,为了让使用者能够从 context, request 以及 response 对象上获取到更多的信息。
然后进到 context.js 里看下 context 的结构:
koa-context里面有一些工具方法,error 处理以及 cookies 的 getter, setter, 最后面是通过代理能够访问到 request 以及 response 的属性,方法等。
Request & Response
从上面的 createContext 方法可以看到, request 以及 response 都是基于 http lib 的 request 以及 response 进行的封装和扩展,具体的属性以及方法解释可以看 Koa 官方的文档:
关于 Koa 和 Express
最后针对 Koa 和 Express 进行一些比较,可以看下 Koa 官方的介绍:
Koa 是一个新的 web 框架,由 Express 幕后的原班人马打造, 致力于成为 web 应用和 API 开发领域中的一个更小、更富有表现力、更健壮的基石。 通过利用 async 函数,Koa 帮你丢弃回调函数,并有力地增强错误处理。 Koa 并没有捆绑任何中间件, 而是提供了一套优雅的方法,帮助您快速而愉快地编写服务端应用程序。
它们属同一团队开发, Koa 更轻量级不会像 Express 一样内置很多中间件,从性能上讲 Koa 会更好一些,从场景上看, 比如我实现一个 Mock Server, Express 反而更容易一些,因为不需要去手动引用和管理依赖。
网友评论