koa用法:
const Koa =require('koa');
const app=new Koa()
app.use((ctx,next)=>{
ctx.body={
name:123
}
})
app.listen(3000,()=>{
console.log('koa...')
})
分析
1.ctx涉及上下文、getter、setter
2.next涉及合成函数compose
request.js
module.exports = {
get url() {
return this.req.url;
},
get method(){
return this.req.method.toLowerCase()
}
};
response.js
module.exports = {
get body() {
return this._body;
},
set body(val) {
this._body = val;//内部变量
}
};
context.js
module.exports = {
get url() {
return this.request.url;
},
get body() {
return this.response.body;
},
set body(val) {
this.response.body = val;
},
get method() {
return this.request.method
}
};
compose.js
洋葱模型,中间件
function compose(middlewares){
return function(ctx){
return dispatch(0);
function dispatch(i){
let fn=middlewares[i]
if(!fn){Promise.resolve()}
Promise.resolve(
fn(ctx,function next(){
return dispatch(i+1)
})
)
}
}
}
koa.js
class Kkb{
constructor(){
this.middlewares = []
}
listen(...args){
const server=http.createServer(async (req,res)=>{
// 创建上下文
let ctx = this.createContext(req, res);
const fn = this.compose(this.middlewares)
await fn(ctx)
res.end(ctx.body);
})
server.listen(...args)
}
use(middleware){
this.middlewares.push(middleware)
}
createContext(req,res){
const ctx=Object.create(context)//里面用到了this.request
ctx.request=Object.create(request)//里面用到了原生的req
ctx.response=Object.create(response)
//以上两部把上下文和request连起来
ctx.req=ctx.request.req=req//想下图,连接剩下的四条线
ctx.res=ctx.response.res=res
return ctx
}
//合成函数
compose(middlewares){
return function(ctx){
return dispatch(0);
function dispatch(i){
let fn=middlewares[i]
if(!fn){Promise.resolve()}
Promise.resolve(
fn(ctx,function next(){
return dispatch(i+1)
})
)
}
}
}
}
通过以上就基本上实现了koa
上下文连接的图解: