最近做了个图书分享的小程序项目,后台用的腾讯云管理后台下的demo,看了看源码是Koa2的代码,下面的是个人的拙见,自己构建了koa,来更好的理解koa.
可能很多地方不对,希望各位大佬看到的给指正,本人就是一个还没毕业的菜鸟而已…,别让我走太多弯路
首先介绍一下koa:(下面的话你们可能不想听,但我还是要说)
Koa 是一个新的 web 框架,由 Express 幕后的原班人马打造, 致力于成为 web 应用和 API 开发领域中的一个更小、更富有表现力、更健壮的基石。 通过利用 async 函数,Koa 帮你丢弃回调函数,并有力地增强错误处理。 Koa 并没有捆绑任何中间件, 而是提供了一套优雅的方法,帮助您快速而愉快地编写服务端应用程序。
let’s go!!
Step1:浅层封装http模块
【node需要是7.6+版本之上,安装了nodemon最好不过,本人就是使用nodemon运行的】
1.我们先来看一下原生node的对http模块以及创建服务的过程
上代码:
//引入nodejs自带的http模块
const http = require('http');
//创建服务
//req:request请求
//res:response相应
//创建服务传入的回调中的两个参数
const server = http.createServer((req,res)=>{
//重写响应头
res.writeHead(200);
//打印到页面
//注意:创建的服务中必须有一个end,里面的内容会打印到页面上去
res.end("hello PG13");
});
//监听端口9090,监听成功后可以传递一个回调函数,当然参数是可选的
server.listen(9090,()=>{
console.log("9090正在被监听");
})
使用nodemon编译运行的结果截图:
页面上会打印一个hello PG13
然后我们自己实现一个koa的http模块,创建一个服务
新建一个application.js
代码如下:
const http = require('http');
class Application{
constructor(){
this.callback = ()=>{
}
}
use(callback){
this.callback = callback;
}
listen(...args){
const server = http.createServer((req,res)=>{
this.callback(req,res);
});
server.listen(...args);
}
}
module.exports = Application;
我们将sever.js改造一下:
const koaPG13 = require('./application');
const app = new koaPG13();
app.use((req,res)=>{
res.writeHead(200);
res.end("hello PG13");
});
app.listen(9090,()=>{
console.log("9090正在被监听");
})
执行以后,页面上也会正常显示’hello PG13’
Step2:封装Ctx对象
application.js中代码:
const http = require('http');
let request = {
get url(){
return this.req.url
}
}
let response = {
get body(){
return this._body
},
set body(val){
this._body = val
}
}
let context = {
get url(){
return this.request.url
},
get body(){
return this.response.body
},
set body(val){
this.response.body= val
}
}
class Application{
constructor(){
this.callback = ()=>{
},
this.context = context;
this.request = request;
this.response = response;
}
use(callback){
this.callback = callback;
}
listen(...args){
const server = http.createServer(async (req,res)=>{
let ctx = this.createCtx(req,res);
await this.callback(ctx);
ctx.res.end(ctx.body);
// this.callback(req,res);
});
server.listen(...args);
}
createCtx(req,res){
let ctx = 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;
return ctx;
}
}
module.exports = Application;
server.js:
const koaPG13 = require('./application');
const app = new koaPG13();
// app.use((req,res)=>{
// res.writeHead(200);
// res.end("hello PG13");
// });
app.use(async ctx=>{
ctx.body = 'hello koaPG13'+ctx.url
})
app.listen(9090,()=>{
console.log("9090正在被监听");
})
执行编译后,页面会打印成:
Step3 实现中间件机制
解释中间件机制的模型图
实现一个同步的compose
function add(x,y){
return x+y
}
function double(z){
return z*2
}
const middlewares = [add, double] //中间件:两个函数
let len = middlewares.length //2
function compose(midds){
console.log(midds);
return (...args)=>{
// 初始值
console.log(...args);
let res = midds[0](...args)
for(let i=1;i<len;i++){
res = midds[i](res)
}
return res
}
}
const fn = compose(middlewares)
const res = fn(1,2);
console.log(res)
打印为6
Step4 实现精简版Koa
实现next 异步的中间件
async function fn1(next){
console.log('fn1')
await next()
console.log('end fn1')
}
async function fn2(next){
console.log('fn2')
await delay()
await next()
console.log('end fn2')
}
function fn3(next){
console.log('fn3')
}
function delay(){
return new Promise((reslove,reject)=>{
setTimeout(()=>{
reslove()
},2000)
})
}
function compose (middlewares){
return function(){
return dispatch(0)
function dispatch(i){
let fn = middlewares[i]
if(!fn){
return Promise.resolve()
}
return Promise.resolve(fn(function next(){
return dispatch(i+1)
}))
}
}
}
会以洋葱圈的形式执行!
over!
比较糙,见谅,更多的是我自己做的笔记