手写Koa2

  目录

Koa2源码实现

Koa2使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
const Koa = require('koa');
// const Koa = require('./my-koa');
const app = new Koa();

const mid1 = async (ctx, next)=> {
console.log('mid1');
ctx.body = 'mid1Before-';
await next();
ctx.body += 'mid1After';
}

const mid2 = async (ctx, next)=> {
console.log('mid2');
ctx.body += 'mid2Before-';
await next();
ctx.body += 'mid2After-';
}

const mid3 = async (ctx, next)=> {
console.log('mid3');
ctx.body += 'mid3Before-';
await next();
ctx.body += 'mid3After-';
}

app.use(mid1).use(mid2).use(mid3);
app.listen(3005, ()=> {
console.log('web server is on at port 3005');
});

实现自己的Koa

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
const http = require('http');
const context = {
_body: null,
get body() {
return this._body;
},
set body(val) {
this._body = val;
}
}

class MyKoa {
constructor() {
this.middlewares = [];
}
use(middleware) {
middleware&&this.middlewares.push(middleware);
return this;
}
listen(...args) {
const server = http.createServer(async (req, res)=> {
const ctx = this.createContext(req, res);
const fn = this.compose(this.middlewares);
await fn(ctx);
res.end(ctx.body);
});
server.listen(...args);
}
createContext(req, res) {
const ctx = Object.create(context);
ctx.req = req;
ctx.res = res;
return ctx;
}
compose(middlewares) {
return async (ctx)=> {
return dispatch(0);
function dispatch(index) {
const fn = middlewares[index];
if(!fn) {
return Promise.resolve();
}
return Promise.resolve(fn(ctx, ()=> {
return dispatch(index + 1);
}));
}
}
}
}

module.exports = MyKoa;

总结

Koa2的核心代码不多,但是功能无比强大,主要是它的中间件特别多,利用中间件来完成很多工作。