Appearance
koa 中间件机制实现原理
使用 koa 的同学一定会有如下疑问:
- koa 的中间件机制是如何实现?
- 为什么中间件必须是 generator function?
- next 实参指向是什么?为什么可以通过 yield next 可以执行下一个中间件?
- 为什么中间件从上到下执行完后,可以从下到上执行 yield next 后的逻辑?
接下来我们通过实现简单的 koa 框架(剥离除中间件外所有的逻辑)来解答上述问题,这个框架的名字叫 SimpleKoa:
javascript
var co = require('co');
function SimpleKoa(){
this.middlewares = [];
}
SimpleKoa.prototype = {
//注入个中间件
use: function(gf){
this.middlewares.push(gf);
},
//执行中间件
listen: function(){
this._run();
},
_run: function(){
var ctx = this;
var middlewares = ctx.middlewares;
return co(function *(){
var prev = null;
var i = middlewares.length;
//从最后一个中间件到第一个中间件的顺序开始遍历
while (i--) {
//实际koa的ctx应该指向server的上下文,这里做了简化
//prev 将前面一个中间件传递给当前中间件
prev = middlewares[i].call(ctx, prev);
}
//执行第一个中间件
yield prev;
})();
}
};
写个 demo 印证下中间件执行顺序:
javascript
var app = new SimpleKoa();
app.use(function *(next){
this.body = '1';
yield next;
this.body += '5';
console.log(this.body);
});
app.use(function *(next){
this.body += '2';
yield next;
this.body += '4';
});
app.use(function *(next){
this.body += '3';
});
app.listen();
执行后控制台输出:123456,对照 koa 中间件执行顺序,完全一致!寥寥几行代码,我们就实现了 koa 的中间件机制!这就是 co 的魔力。