中间件使用
通过 app.use 使用多个中间件:
const app = new Koa();
app.use(async (ctx, next) => {
//...
await next();
//...
});
app.use(async (ctx, next) => {
//...
await next();
//...
});
// 最后一个中间件不需要 next
app.use(async ctx => {
ctx.body = "Hello World";
});
//...
中间件总体框架
中间件总体流程的核心代码如下:
class Application extends Emitter {
constructor() {
super();
this.middleware = [];
},
use(fn) {
this.middleware.push(fn);
return this;
},
callback() {
const fn = compose(this.middleware);
return function(req, res) {
return fn(ctx);
};
},
listen(...args) {
const server = http.createServer(this.callback());
return server.listen(...args);
}
}
核心 compose 方法实现
function compose(middleware) {
return function(context, next) {
// last called middleware #
let index = -1;
return dispatch(0);
function dispatch(i) {
index = i;
let fn = middleware[i];
if (i === middleware.length) fn = next;
if (!fn) return Promise.resolve();
try {
return Promise.resolve(fn(context, dispatch.bind(null, i + 1)));
} catch (err) {
return Promise.reject(err);
}
}
};
}