koa&中间件
koa的线上访问地址https://www.npmjs.com/package/koa。在这里有koa的安装方法基本用法。中间件模型也就是洋葱模型。koa使用ES6的generator实现中间件模型。这里不解释generator。
generator实现中间件模型原理
koa的核心部分就其巧妙的利用generator实现中间件模型。若是实现中间件模型,下面的代码应该打印0,1,2,3
。
app.use(function*(next) {
console.log(0);
yield next;
console.log(3);
});
app.use(function*(next) {
console.log(1);
yield next;
console.log(2);
})
app.go();
核心的实现原理可以用下面十几行代码解释。
var midwares = [];
var app = {};
app.use = function(gene) {
midwares.push(gene);
}
app.compose = function () {
var i = midwares.length;
var all = function *noop(){}();
while(i --) {
all = midwares[i](all);
}
return all;
};
app.go = function () {
var all = app.compose();
var q = [];
while(all) {
q.push(all);
all = all.next().value;
}
while(q.length && q.pop().next()){}
}
首先use方法的功能十分简单,就是收集所有的中间件。
在执行之前,要使用compose方法将所有的中间件组合在一起,返回一个all。这里是用每个中间件生成一个generator,这个generator里面的next
参数都是下一个中间件生成的generator。这样就可以通过mid1.next().value
访问mid2
。
执行的时候通过all.next().value
访问下一个中间件生成的generator,同时将挂起的generator入栈,直到下一个中间件中没有yield next
。最后将所有挂起的generator next掉。整个执行就结束了。
但是在实际当中app.go
是由co来完成迭代的,co要求参数是一个generator,co将generator自动迭代。所以需要将compose略微改造。所以我们看到如下最终的,也是官方的compose方法
app.compose = function () {
return function *(next){
if (!next) next = noop();
var i = middleware.length;
while (i--) {
next = middleware[i].call(this, next);
}
return yield *next;
}
}
可能具体细节略有出入,但是如上,使用generator实现中间件并不高深。感受下。(系原创,转载请指明出处)