框架的实现

上一节的构思,头脑很明确的知道了方向和切入点,而实现又是另外一回事儿。

回顾一下昨天的代码,App.js文件是框架的核心部分,static.js是一个中间件,然后通过app.use方法加入static中间件。

var app = ...
var middle1 = ... 
var middle2 = ...
app.use(middle1)   // 加入中间件
app.use(middle2)   // 加入第二个中间件,中间件有先后顺序,middle1会先于middle2执行。

前者中间件决定后者是否执行

要保证中间件有顺序的执行,光靠中间件数组的执行顺序是不够的,因为这里牵扯到异步执行和延迟执行的问题,下面用个小例子说明。

function m1(){
    setTimeout(function(){
        console.log("m1");
    })     
}

function m2(){
    console.log("m2");
}
m1();
m2();

打印结果是
m2
m1

而不是
m1
m2

(小胖问道:那如何保证其顺序呢?)

保证其顺序的一个方法,是给中间件函数内部一个next函数,当执行next函数时,表示中间件自身已执行完成,下狠心把权力交给下一个中间件,依次类推,也就是说,中间件自身内部不调用next函数,那么下个中间件就不会被执行。

下面,回顾一下昨天App.js的构造函数的实现代码,下面是简化后的伪代码,只保留了关键说明的代码。可以参看昨天的完整代码。

function App(){

    // 插件有序列表
    var middleList = [];

    // request事件响应函数
    function handle(req,res){
            var middleIndex = 0; // 插件索引
            execMiddle();  // 执行第一个中间件

            // 执行这个函数时,会自动执行下一个middle插件。
            function next(){
                middleIndex += 1;
                execMiddle();
            }

            // 执行插件函数
            function execMiddle(){
                var middle = middleList[middleIndex];
                middle(req,res,next);  // 执行
            }        
        }
    }
    this._server = http.createServer(handle);
}

而App的use方法很简单,就是把中间件加入到middleList 数组中。

下一节将开发两个演示性插件,并运行,观看其效果。