三余无梦

冬者岁之余,夜者日之余,阴雨者时之余也

Koa-compose Code Reading

compose

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function compose(middleware) {
   return function *(next) {
        var i = middleware.length;   
        var prev = next || noop ();
        var curr;
        
        while (i--) {
            curr = middleware[1];    
            prev = curr.call(this, prev); // 
        }

        yield *prev;
   } 
}

看下例的运行效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var co = require('co');

var stack = [];
var arr = [];
stack.push(function *(next) {
    arr.push(1);    
    yield next;
    arr.push(3);
});
stack.push(function *(next){
    arr.push(2);    
    yield next;
    arr.push(4)
});

co(compose(stack)) (function (err) {
    if (err) throw err;   
    console.log(arr); // 输出 [1, 2, 3, 4], 从输出可以看到其执行顺序
});

从上例的程序可以看到koa。koa在加载中间件时是通过co 和 compose来按次序拨开一层一层的middleware。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
co (function *() {
    var arr = []
    var funa = function *(next) {
        arr.push(1);    
        yield *next;
        arr.push(3);
    };
    var funb = function *(next) {
        arr.push(2);
        yield *next;
        arr.push(4)
    };
    funa ();
    funb ();
    return arr;
})(function (err, items) {
 if (err) {
    console.log(err);     
 }
 console.log(items);    
});