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 Nov 30, 2024. It is now read-only.
constKoa=require('koa')constapp=newKoa()app.use(async(ctx,next)=>{console.log('@@ start 1')next()console.log('@@ end 1')})app.use(async(ctx,next)=>{console.log('@@ start 2')next()console.log('@@ end 2')})app.listen(3000)
use(fn){if(typeoffn!=='function')thrownewTypeError('middleware must be a function!');if(isGeneratorFunction(fn)){deprecate('Support for generators will be removed in v3. '+'See the documentation for examples of how to convert old middleware '+'https://github.com/koajs/koa/blob/master/docs/migration.md');fn=convert(fn);}debug('use %s',fn._name||fn.name||'-');this.middleware.push(fn);returnthis;}
之前梳理
Redux
的时候,说到它的中间件的处理方式与koa
是一样的,所以就想到那就把koa
也看一遍吧,梳理一遍吧。koa
非常的简洁适合阅读,该文章分析的当前版本为2.8.1
。目录结构
通过github上的
package.json
可以看到,koa
的入口文件是lib/application.js
。整个lib
才四个文件,当然里面引入了一些其他的工具函数。下面从程序入口出发,也就是
application.js
。application.js
先看一下关键的相关依赖:
可以看到,入口文件把其他三个
js
文件都引入进来,然后主要引入了http
、koa-compose
和events
,其他的我先省略了。koa-compose
库主要是为了对koa
的中间件进行合并的工具函数,其他两个都是node
的标准库。该文件使用
module.exports = class Application extends Emitter {...}
导出了koa
类。这里看到Application
继承了Emitter
,所有它也包含了异步事件的处理能力,后面可以看到koa
的错误处理会使用到Emitter
提供的事件模型方法。构造函数
重点可以看到:
middleware
属性,是用来存放之后添加的中间件的。Object.create
方法,分别创建了一个对象,这些对象的原型分别指向context
、request
和response
,分别对应最开始引入的其他三个js
文件。到这里,先写一份使用
koa
的使用的示例代码,主要引导整个处理流程:use
从上往下,当执行
new Koa()
的时候,也就是调用上面说的构造函数。来到app.use
添加中间件的时候:use
函数会判断传入的中间件如果是generator
,就会使用convert
函数去将生成器转成类async/await
函数,这个兼容会在3.*
之后去掉。核心的一步就是将函数添加到了this.middleware
队列里面。listen
这里就是正式的使用
http
库提供的createServer
方法来创建一个web
服务了,并且监听相应的端口。根据
http.createServer
的文档和使用,可以肯定这里的this.callback()
函数执行会返回一个(req, res) => {}
这样的函数。callback
首先就将已经注册的中间件进行了合并,这里就是经典的洋葱模型中间件机制。然后判断了一下是否有过错误监听,没有的话就添加一个,这里利用了
Emitter
的事件模型,最后返回一个http.createServer
能够使用的回调函数。到这里,整个服务的启动流程已经结束。
处理请求
当服务收到请求,最后执行的就是传入
http.createServer
的回调函数。在处理请求之前,首先使用
this.createContext
将请求和响应对象进行了聚合封装成了ctx
对象,然后再交给handleRequest
函数去处理。createContext
首先通过
Object.create
函数去创建了一个原型为this.context
的空对象,之后就是为这个对象赋值了,可以看到在平时使用的时候访问的一些属性是怎么来的了,他们之间的关系是怎么样的可以很清楚的看见。handleRequest
默认给响应状态设置为404,然后创建一个统一错误处理的回调函数和响应处理函数函数。将
ctx
传给被合并后的中间件,然后使用then
和catch
分别来处理中间件等正常处理和异常监控。respond
当请求经过了所有的中间件处理之后,在最后调用
handleResponse
方法,然后去执行respond
函数,最终组织响应对象,进行服务响应。看到
body
的类型支持Buffer
、string
、Stream
和JSON
。小结
通过梳理
application.js
可以知道,它核心主要是做了这样几个事情:http
启动web
服务,创建koa
实例。The text was updated successfully, but these errors were encountered: