koa源码分析(一) - application.js
brunoyang opened this issue · 4 comments
本文分为四个部分,分别对应源码的四个文件。
- koa源码分析(一) - application.js
- koa源码分析(二) - context.js
- koa源码分析(三) - request.js
- koa源码分析(四) - response.js
- koa源码分析(五) - koa 2.0
仓库:https://github.com/koajs/koa
官方介绍:Koa is a new web framework designed by the team behind Express, which aims to be a smaller, more expressive, and more robust foundation for web applications and APIs. Through leveraging generators Koa allows you to ditch callbacks and greatly increase error-handling. Koa does not bundle any middleware within core, and provides an elegant suite of methods that make writing servers fast and enjoyable.
本文根据koa@1.0.0撰写。
依赖
- debug:debug源码分析;
- compose_es7:与co.wrap相似,不过能够接受 async/await 函数;
- onFinished:捕捉finish或error事件,并根据第二个参数执行回调;
- compose:compose_es7的简化版,只接受generator;
- isJSON:顾名思义,判断传入参数是否为JSON;
- statuses:将http码分为三类,redirect、empty以及retry,然后根据传入的http来判断属于哪一类;
- accepts:根据req的内容判断(content negotiation)字段,如accept,Accept-Encoding,Accept-Language等字段对这些字段进行格式化,方便后续处理;
- only:只返回在传入参数里所包含的字段;
- co:co源码解析
源码解析
Application
koi
暴露了Application
对象作为入口,Application
的几个属性挑重要的讲:middleware
,context
。request
,response
会在后续文章里讲到。
middleware
middleware
是一个数组,在这里特称为中间件数组,数组元素要求是generator
函数。当然开启了experimental
就可以用async/await
了。
middleware
数组是如何工作的可以参考下图
context
将http
请求和相应进行包装,得到包含request
和response
的对象,对象所具体包含的内容在下面会有写到。
Application.prototype
Application
n的prototype
继承自event.Emitte
r的prototype
,并挂载了多个方法。
listen
这是http.createServer(app.callback()).listen(...)
的简写,重要的是当中的callback
函数。
callback
函数的第一行就是将response
函数作为了middleware
数组的第一个元素,所以我们再来看一下response
函数。
response
函数的第一句,就是个yield *next
,也就是说在req
进入中间件数组时response
函数不作处理。那什么时候处理呢?看一下上面这张图,可以看到,response
函数在之后的所有中间件都执行完成后,对res
做最后一步的处理。
middleware
数组放入compose
后,会得到一个generator
函数,这个generator
函数的效果相当于是将多个中间件组合成一个,来让co
可以按顺序执行。最后,传入ctx
,完成一次http
请求。
createContext
那ctx
从哪来的呢,是由createContext
函数创建的。返回的结果形如下面的代码。request
和response
是koa
生成的对象,res
和req
是node
原生的http
对象,当需要访问原生对象时,可以通过this.res
来访问到,但并不推荐这样做,推荐直接访问request
对象。
{
request: {
url: '/',
method: 'GET',
req: <origin node >
...
},
response: {
}
app: {
subdomainOffset: 2,
env: 'development'
},
originalUrl: '/',
req: '<original node req>',
res: '<original node res>',
socket: '<original node socket>'
}
inspect/toJSON
返回配置的参数subdomainOffset
和env
。
2.0 快出来了,有时间也分析一下吧
前来拜读
mark