题外话:事实证明,扩展自建类型是如此的不靠谱,果断放弃掉了自建库这件事,但是暂时不打算引入underscore,先使用完全原生的js方法写吧。后期如果发现却是需要依赖工具库,再添加不迟。
今天大体上完成了Dispatcher这部分。
其实并不复杂,流程如下:
1、请求到来,首先判定是否为静态文件请求,如果是,则直接返回静态文件(这里后期要加入静态文件缓存)
2、拆分URL,根据以下规则来调用相应的模块处理请求:
'/':检测./views.js模块,并调用其中的index()函数处理请求
'/aaa': 检测./views.js模块,如果其中包含函数aaa(),则调用该函数;
未找到,则调用./modules/aaa/views.js中的index()函数
'/aaa/bbb':调用./modules/aaa/views.js中的bbb()函数
'/aaa/bbb/ccc/ddd':调用./modules/aaa/views.js中的bbb()函数
3、如果前面的函数查找失败,则返回404
代码部分:
this.handle = function(request, response){
var reqParam = url.parse(request.url);
if(requestStatics(reqParam, response)){
handleStatics(reqParam, response);
return;
}
var view = findView(reqParam.pathname);
if(view){
// organize the arguments of view function
var args = [];
var param = wrapParam(reqParam);
var paths = splitPath(reqParam.pathname);
if(paths.length > 2){
for(var i = 2; i < paths.length; i++){
args.push(paths[i]);
}
}
args.push(param);
args.push(request);
args.push(response);
view.apply(this, args);
return;
}
option.on404(request, response);
}
逻辑上就如同前面这个流程一样。
细节上有一个关于调用函数时参数的问题,设计如下:
请求中所有的query string parameters,将进行包裹。如/aaa?name=jeky&age=25会被转换为:
var param = {name : 'jeky', age : '25'},一般来讲,被调用函数的第一个参数为这个。
特别的,对于url中目录级别大于2的情形,如(/aaa/bbb/ccc/ddd),在调用时会将大于2的部分也传入函数,顺序为第一个参数'ccc',第二个为'ddd'。
函数的最后两个参数为request和response,node.js自带的,特殊情况下用得上。
总例,对于/aaa/bbb/ccc/ddd?name=jeky&age=25相当于:
var param = {
name : 'jeky',
age : '25'
}
bbb('ccc', 'ddd', param, request, response);
下面另一件事情就是引入了Dispatcher的配置:
var defaultOption = {
modulePath : 'modules',
indexName : 'index',
viewFilename : 'views.js'
on404 : on404DefaultHandler,
on500 : on500DefaultHandler,
}
这部分可以在初始化Dispatcher的时候进行修改。
剩下的工作就是需要把Dispatcher绑定在Server上就可以啦
require('./dispatcher.js');
var dispatcher = new Dispatcher();
http.createServer(function (req, res) {
dispatcher.handle(req, res);
}).listen(8080);