Node Web学习笔记(11)-路由模块的进一步优化

下面是上一次笔记的路由器模块代码,这里再次贴出来的原因是今天它是主角,并且我觉得今天对路由器模块的改进相对与之前的所有变动都是最重要的。

1
2
3
4
5
6
7
8
9
10
11
12
//router.js
var url = require('url');
var reqHandler = require("./reqHandler.js");
function route(req,res){
var pathname = url.parse(req.url).pathname;
var handle = new reqHandler();
if (pathname == "/") handle.start(res);
else if(pathname == "/index") handle.start(res);
else if(pathname == "/show") handle.show(res);
else handle.notFound(res);
}
exports.route = route;

如何才能避免在路由器模块中有if...else判断逻辑的语句呢?那么就不能在路由器模块中去判断pathname,也可以说,不用去判断路径,而应该是我指定路径去访问,站在服务器的角度来考虑的话,应该是我服务器上有哪些资源可以让客户端去访问,而不是你客户端想访问啥就访问啥。

这么想的话,就不用路由器去判断路径了,而是访问请求来了,我看看在我的请求列表中有没有这个你要的请求。有的话直接转给请求模块,没有的话,返回404

这样路由器的功能再一次被精简,判断路劲的功能也从路由器中剔除。路由器剩下要干的,就是给我一个路径,我来转发。那么问题就来了:

  • 首先,如何建立一个类似『资源列表』的东西?
  • 其次,如何实现访问路径和资源列表的对比?

在 JavaScript中,对象就是一个键/值对的集合 – 你可以把 JavaScript 的对象想象成一个键为字符串类型的字典。
但如果 JavaScript 的对象仅仅是键/值对的集合,它又怎么会拥有方法呢?好吧,这里的值可以是字符串、数字或者……函数。

这里我们把每一个可访问的路径(字符串)当做一个集合中的键,然后赋予它处理请求函数的值。这样『资源列表』就出来了;然后通过判断是否有这个可访问的『键值对』就行了。改写后路由器模块代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//router.js
var url = require('url');
var reqHandler = require("./reqHandler.js");
var reqHandle = new reqHandler();
var handle = {}; //创建一个集合,也是一个对象
handle["/"] = reqHandle.start;
handle["/index"] = reqHandle.start;
handle["/show"] = reqHandle.show;
function route(req,res){
var pathname = url.parse(req.url).pathname;
if (typeof handle[pathname] == 'function'){ //判断该路径的值是否有处理请求函数。有,直接执行函数
return handle[pathname](res);
}else{
return reqHandle.notFound;
}
}
exports.route = route;

这么看,一长串的if…else语句就变成了一个单独的判断语句,当你想要添加页面的时候,直接在『资源列表』里加上对应的『键值对』就行了。

也许你觉得这还不是一样,路由器模块里的代码还不是一样的不断增加,每增加一个页面就要多增加一行。没错,但是能想到以这种方式来替代判断语句,已经成功了99%,为什么这么说,因为这种处理逻辑的转换,把这里的判断逻辑转换成了一个handle对象(对象就是一个集合),想要移走这个handle对象真是再容易不过了。

今天的笔记就总结到这了,剩下1%的工作(移走handle对象)就留到下次笔记的内容一带而过。对了提醒一下,其他模块的代码和上次笔记一模一样,这里就不再贴出来了。虽说只变动了router路由器模块代码,但是我觉得这次的内容是进步最大的。