You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository has been archived by the owner on Aug 7, 2024. It is now read-only.
Methods can also have the property of "idempotence" in that (aside from error or expiration issues) the side-effects of N > 0 identical requests is the same as for a single request.
目录
koa2 的目录结构相当整洁,只有四个文件,搭起了整个 server 的框架,koa 只是负「开头」(接受请求)和「结尾」(响应请求),对请求的处理都是由中间件来实现。
application.js:负责串联起 context request response 和中间件
context.js:一次请求的上下文
request.js:koa 中的请求
response.js:koa 中的响应
流程
我们从官网给的一个最小化的 demo 一步一步解析 koa 的源码了解其整个流程:
初始化
Koa 这个类是从
application.js
中导入的Application
,Application
继承自 Emmiter,Emmiter 唯一的作用就是去回调onerror
事件,因为一次成功的 HTTP 请求会由 HTTP 模块来负责回调,但 error 是可能在中间件中 throw 出来的,此时就需要去通知 app 发生错误了。这在运行中的部分会有分析。既然是初始化,就来看 koa 的构造函数:
request 和 response 就是继承自
./request.js
和./response
,./request.js
和./response
中的 request 和 response 做的事情并不复杂,就是将 Node 原生的 http 的 req 和 res 再次做了封装,便于读取和设置,每个属性和方法的封装都不复杂,具体的属性和方法 koa 的文档上已经写的很清楚了,这里就不再介绍了。至于 context,context 是一个「传递的纽带」,每个中间件传递的就是 context,它承载了这次访问的所有内容,直到其被最终 response 掉。
其实看源码 context 就是一个普通的对象,普通对象就可以完成「记录并传递」这个作用,context 还额外提供了 error 和 cookie 的处理,因为 app 是继承自 Emmiter 只有它能订阅
onerror
事件,所以传递的 context 要包裹一个 app 的onerror
事件来在中间件中传递。运行中
运行中有一个很重要和基本的概念就是:HTTP 请求是幂等的。
一次和多次请求某一个资源应该具有同样的副作用,也就是说每个 HTTP 请求都会有一套全新的 context,request,response。
整个运行中的流程如下:
核心代码如下:
构建新的 context,request,response,其中 context/request/response/app 中各种引用对方来保证各自方便的传递。
这里比较有意思的是,在构造函数中,this.context 是继承自
context.js
文件,这里在每次请求时又继承自this.context
。这样的好处是你可以为你的 app 设定一个类似模板的 context,这样一来每个请求的 context 在继承时就会有一些预设的方法或属性,同理 this.request 和 this.response。
调用 http 的端口监听
构建 http 的回调函数
中间件及异常处理
koa 自带的成功 res 处理
在初始化中提到了,koa 继承自 Emiiter,是为了处理可能在任意时间抛出的异常所以订阅了
error
事件。error 处理有两个层面,一个是 app 层面全局的(主要负责 log),另一个是一次响应过程中的 error 处理(主要决定响应的结果),koa 有一个默认 app-level 的 onerror 事件,用来输出错误日志。The text was updated successfully, but these errors were encountered: