本来可以用简单的setter和getter去设置每一个方法,但是由于context对象定义方法比较简单和规范,在koa源码里可以看到,koa源码用的是__defineSetter__和__defineSetter__来代替setter/getter每一个属性的读取设置,这样做主要是方便拓展和精简了写法,当我们需要代理更多的res和req的方法的时候,可以向context.js文件里面的数组对象里面添加对应的方法名和属性名即可。
koa源码怎么用
目前为止,我们已经得到了request、response、context三个模块对象了,接下来就是将request、response所有方法挂载到context下,让context实现它的承上启下的作用,修改application.js文件,添加如下代码:
lethttp=require('http');
letcontext=require('./context');
letrequest=require('./request');
letresponse=require('./response');
createContext(req,res){
letctx=Object.create(this.context);
ctx.request=Object.create(this.request);
ctx.response=Object.create(this.response);
ctx.req=ctx.request.req=req;
ctx.res=ctx.response.res=res;
returnctx;
}
koa添加模块
可以看到,我们添加了createContext这个方法,这个方法是关键,它通过Object.create创建了ctx,并将request和response挂载到了ctx上面,将原生的req和res挂载到了ctx的子属性上,往回看一下
总之,context/request/response.js文件,就能知道当时使用的this.res或者this.response之类的是从哪里来的了,koa原来是在这个createContext方法中挂载到了对应的实例上,构建了运行时上下文ctx之后,我们的app.use回调函数参数就都基于ctx了。