浅析koa源码

114 阅读1分钟

初始化:

middleware 中间件数组

context 默认上下文对象

request 默认必备属性对象,主要是设置一些get set方法

response 默认必备属性对象,主要是设置一些get set方法

listen

调用原生node方法http.createServe创建http服务,传入回调函数this.callBack()

use

把use中传入的函数参数放进middleware中

callBack

把middleware中的回调函数作利用koa-compose做一个整合

强化handleRequest的能力

每次监听到请求都会执行一次callBack的回调

callback () { 
    const fn = compose(this.middleware) 
    if (!this.listenerCount('error')) this.on('error', this.onerror) 
    const handleRequest = (req, res) => { 
        // 创建全局上下文,req res 原生的 
        const ctx = this.createContext(req, res) 
        return this.handleRequest(ctx, fn) } 
    return handleRequest 
}

createContext

创建ctx上下文,这是在use api中使用到的ctx上下文 ctx.request是context经过封装的请求对象,ctx.req是context提供的node.js原生HTTP请求对象,同理ctx.response是context经过封装的响应对象,ctx.res是context提供的node.js原生HTTP响应对象。

createContext (req, res) { 
    // context文件中初始化的一些属性 
    const context = Object.create(this.context) 
    // request文件中初始化的一些属性 
    const request = context.request = Object.create(this.request) 
    // response文件中初始化的一些属性 
    const response = context.response = Object.create(this.response) 
    context.app = request.app = response.app = this 
    // 原生http请求的request和初始化一些request属性的整合 
    context.req = request.req = response.req = req 
    // 原生http请求的response和初始化一些response属性的整合 
    context.res = request.res = response.res = res 
    request.ctx = response.ctx = context 
    request.response = response 
    response.request = request 
    context.originalUrl = request.originalUrl = req.url 
    context.state = {} 
    return context 
}

handleRequest

调用整合的中间件函数,并组装请求数据使用原生的end()发送请求

handleRequest (ctx, fnMiddleware) { 
    const res = ctx.res 
    // 初始化状态404 
    res.statusCode = 404 
    // 报错时候执行的方法 
    const onerror = err => ctx.onerror(err) 
    // 正常执行的时候执行的方法 
    const handleResponse = () => respond(ctx) 
    onFinished(res, onerror) 
    return fnMiddleware(ctx).then(handleResponse).catch(onerror) 
}

原生的http请求如下:

var http = require('http'); 
http.createServer(function (request, response){ 
    response.writeHead(200, {'Content-Type': 'text/plain'}); 
    response.write("Hello World"); 
    response.end(); 
}).listen(8080, '127.0.0.1');