介绍
来自官方文档简介:Koa 是一个新的 web 框架,由 Express 幕后的原班人马打造, 致力于成为 web 应用和 API 开发领域中的一个更小、更富有表现力、更健壮的基石。 通过利用 async 函数,Koa 帮你丢弃回调函数,并有力地增强错误处理。 Koa 并没有捆绑任何中间件, 而是提供了一套优雅的方法,帮助您快速而愉快地编写服务端应用程序。
Koa和原生http的区别
Koa的优势在于显著的提高开发效率,在koa中中间件的概念很明显。中间件有 listen,use,ctx,next 。Koa为什么可以提高效率?我们来分析一下它的源码。
源码分析
中间件 listen
listen中间件就是一个语法糖,其实他里面还是http的listen,只是包装的一层。
listen(...args){
let server=http.createServer(this.handleRequest.bind(this));
server.listen(...args);
}
中间件 use
在我们使用use的时候,会发现里面的函数会立即执行,说明use的源码中有一个回调函数可以让它立即执行。
use(fn){//use里传入回调函数
this.fn=fn;//执行回调函数,保证其在listen后执行
}
中间件 ctx
首先我们知道在使用koa的时候,我们不管是请求操作还是响应操作,都是使用ctx调用,这也是Koa框架的优势,让代码更简单。现在我们就来探究一下,ctx是怎么实现的?
创建一个context.js 的文件
//ctx 怎么来的
let proto ={
// url:request.url
}
function defineGetter(prop,name){ //代理函数
proto.__defineGetter__(name,function(){
return this[prop][name] //this == ctx
})
}
defineGetter('request','url') // url==request.url
defineGetter('request','path')
module.exports = proto
在application.js 中
createContext(req,res){//构建ctx
const ctx=Object.create(this.context)//使ctx具备三种属性 交叉赋值
const request=ctx.request=Object.create(this.request)
const response=ctx.response=Object.create(this.response)
ctx.req=request.req=response.req=req
ctx.res=request.res=response.res=res
request.ctx=response.ctx=ctx
request.response=response
response.request=request
return ctx
}
request.js
//为什么Koa里面没有req
let url=require('url')
let request ={
// ctx.url == ctx.request.url
get url(){ //整个地址全拿,包括参数
console.log(this);
return this.req.url
},
get path(){ //只拿路径名称
return url.parse(this.req.url).pathname
}
}
module.exports=request
封装Koa模块 application.js
let EventEmitter=require('events')
let http=require('http')
let context=require('./context')
let request=require('./request')
let response=require('./response')
class Koa extends EventEmitter{//继承于event,使我们手写的Koa也能有错误处理机制
constructor(){ //继承到所有属性 构造函数的继承
super();//超级继承
this.fn;
this.context=context;
this.request=request;
this.response=response;
}
use(fn){//use里传入回调函数
this.fn=fn;//执行回调函数,保证其在listen后执行
}
createContext(req,res){//构建ctx
const ctx=Object.create(this.context)//使ctx具备三种属性 交叉赋值
const request=ctx.request=Object.create(this.request)
const response=ctx.response=Object.create(this.response)
ctx.req=request.req=response.req=req
ctx.res=request.res=response.res=res
request.ctx=response.ctx=ctx
request.response=response
response.request=request
return ctx
}
handleRequest(req,res){
let ctx=this.createContext(req,res)
this.fn(ctx)//为了方便调用fn,多封装一层
res.end(ctx.body)
}
listen(...args){
let server=http.createServer(this.handleRequest.bind(this));
server.listen(...args);
}
}
module.exports=Koa;
总结
虽然这篇文章没有把所有的源码都拿出来分析,但我们知道了中间件 listen,use,ctx 的实现,也是了解Koa的第一步。如果这篇文章让你对Koa的源码感兴趣,点击跳转Koa源码,目前是一名大三学生,初学前端,如果有写的不对的地方,欢迎指正,感谢!