koa2中间件机制

koa2中间件的核心实现:数组 + Promise + 递归

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
52
53
54
55
56
57
58
59
60
61
// koa1 使用generator
function compose(middleware) {
return function(context, next) {
// last called middleware #
let index = -1;
return dispatch(0);
function dispatch(i) {

// 防止同一个中间件内多次调用next()
if (i <= index)
return Promise.reject(new Error("next() called multiple times"));
index = i;

let fn = middleware[i];

// 此处的next为undefined
if (i === middleware.length) fn = next;

// 如果当前middleware为空,直接返回,不再处理后续middleware
if (!fn) return Promise.resolve();

// Promise包裹中间件,递归调用
try {
return Promise.resolve(fn(context, dispatch.bind(null, i + 1)));
} catch (err) {
return Promise.reject(err);
}
}
};
}

const m1 = async (ctx, next) => {
console.log(1);
await next();
console.log(2);
}

const m2 = async (ctx, next) => {
console.log(3);
await next();
console.log(4);
}

const middleware = [m1, m2];

const fnMiddleware= compose(middleware);

// koa的context对象
const ctx = {
app: {},
req: {},
res: {}
};

fnMiddleware(ctx).then(() => {
console.log('中间件处理结束')
// const res = ctx.res;
// res.end(ctx.body);
}).catch(err => {
console.error(err);
});

备注: 上面可以看出,中间件是保存在数组中递归执行的,如果中间件数量过多,可能会带来性能影响。

-------------本文结束 感谢您的阅读-------------