30lines Koa Midware core

2016-06-05  本文已影响90人  _Matpgm

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实现中间件并不高深。感受下。(系原创,转载请指明出处)

上一篇下一篇

猜你喜欢

热点阅读