步骤 2 : 路由概念 步骤 3 : 先运行,看到效果,再学习 步骤 4 : 模仿和排错 步骤 5 : 路由代码实现 步骤 6 : 业务处理模块 requestHandlers.js 步骤 7 : 路由模块 router.js 步骤 8 : 服务器模块 server.js 步骤 9 : 入口主模块 index.js 步骤 10 : 思路整理
首先回顾一下前面 server.js 的代码, 这个代码很清爽,也很容易维护。 但是当业务开始略微复杂的时候,怎么办呢?
比如业务上需要通过访问 /listCategory 显示所有的分类,又需要通过访问 /listProduct 显示所有的产品,那么仅仅通过一个 service(request, response) 方法来进行维护不是很麻烦吗 所以在这个时候,就会引入路由的概念了。 var http = require('http');
function service(request, response) {
response.writeHead(200, {'Content-Type': 'text/plain'});
response.end('Hello Node.js');
}
var server = http.createServer(service);
server.listen(8088);
var http = require('http'); function service(request, response) { response.writeHead(200, {'Content-Type': 'text/plain'}); response.end('Hello Node.js'); } var server = http.createServer(service); server.listen(8088);
如果没有路由的概念,那么无论是访问/listCategory路径 还是访问 /listProduct 路径,都是在service(request,response) 函数里做的。
那么引入路由的概念的话,就是指访问 /listCategory 路径,会访问 listCategory函数。 而访问 /listProduct 路径,就会访问 listProduct 函数,这样子维护起来就容易多了。 如代码所示,会提供 listCategory() 函数。 再如图所示,访问地址 /listCategory 就会显示 listCategory() 函数的返回值。 注: 这里的代码仅仅是片段,接下来才会给出完整的代码 function listCategory() {
return "a lot of categorys";
}
function listProduct() {
return "a lot of products";
}
function listCategory() { return "a lot of categorys"; } function listProduct() { return "a lot of products"; }
老规矩,先下载右上角的可运行项目,配置运行起来,确认可用之后,再学习做了哪些步骤以达到这样的效果。
运行方式 : (并不是 node server.js) node index.js 然后访问测试地址: http://127.0.0.1:8088/listCategory 就可以看到如图所示的效果了
在确保可运行项目能够正确无误地运行之后,再严格照着教程的步骤,对代码模仿一遍。
模仿过程难免代码有出入,导致无法得到期望的运行结果,此时此刻通过比较正确答案 ( 可运行项目 ) 和自己的代码,来定位问题所在。 采用这种方式,学习有效果,排错有效率,可以较为明显地提升学习速度,跨过学习路上的各个槛。 推荐使用diffmerge软件,进行文件夹比较。把你自己做的项目文件夹,和我的可运行项目文件夹进行比较。 这个软件很牛逼的,可以知道文件夹里哪两个文件不对,并且很明显地标记出来 这里提供了绿色安装和使用教程:diffmerge 下载和使用教程
为了达到前面的路由效果,需要多个模块协同配合达到这个效果。 所谓的多个模块,其实就是多个.js文件里的多个函数互相配合。
首先是业务处理模块 ,即提供 listCategory函数和listProduct()函数
function listCategory() {
return "a lot of categorys";
}
function listProduct() {
return "a lot of products";
}
exports.listCategory = listCategory;
exports.listProduct = listProduct;
function listCategory() { return "a lot of categorys"; } function listProduct() { return "a lot of products"; } exports.listCategory = listCategory; exports.listProduct = listProduct;
router函数第一个参数 handle 是一个数组,第二个参数是 路径。
这个模块,乍一看会有点晕,要结合后面的模块来看 function route(handle, pathname) {
if (typeof handle[pathname] === 'function') {
return handle[pathname]();
} else {
return pathname + ' is not defined';
}
}
exports.route = route;
function route(handle, pathname) { if (typeof handle[pathname] === 'function') { return handle[pathname](); } else { return pathname + ' is not defined'; } } exports.route = route;
这个就是启动服务器的模块,同样的。。。还是要结合后面的代码来看
var http = require("http");
var url = require("url");
function start(route, handle) {
function onRequest(request, response) {
var pathname = url.parse(request.url).pathname;
var html = route(handle, pathname);
response.writeHead(200, {"Content-Type": "text/plain"});
response.write(html);
response.end();
}
http.createServer(onRequest).listen(8088);
}
exports.start = start;
var http = require("http"); var url = require("url"); function start(route, handle) { function onRequest(request, response) { var pathname = url.parse(request.url).pathname; var html = route(handle, pathname); response.writeHead(200, {"Content-Type": "text/plain"}); response.write(html); response.end(); } http.createServer(onRequest).listen(8088); } exports.start = start;
与以往启动使用 server.js不同,带路由功能,一般都会通过 index.js 启动,所以index.js 就是入口模块。
handle 是一个数组,映射了不同的访问路径与 业务处理模块对应函数的一一对应关系。 handle["/listCategory"] = requestHandlers.listCategory; 这就表示访问路径 /listCategory的话,就会交给函数 requestHandlers.listCategory 来处理。 var server = require("./server");
var router = require("./router");
var requestHandlers = require("./requestHandlers");
var handle = {}
handle["/listCategory"] = requestHandlers.listCategory;
handle["/listProduct"] = requestHandlers.listProduct;
server.start(router.route, handle);
var server = require("./server"); var router = require("./router"); var requestHandlers = require("./requestHandlers"); var handle = {} handle["/listCategory"] = requestHandlers.listCategory; handle["/listProduct"] = requestHandlers.listProduct; server.start(router.route, handle);
1. 通过如下方式启动服务器
node index.js 2. index.js 调用了 server.start 函数,并且传递了 router.js 里route 函数和handle数组作为参数 3. serverl.js 通过了8088端口启动了服务。 然后用 onRequest 函数来处理业务 3.1 在 onRequest 中,首先获取 访问路径 pathname 3.2 然后调用 router.js 的route 函数,并把pathname 和 handle数组传递进去 4. 在router.js 中,通过pathname为下标获调用真正的业务函数,并把业务函数的返回值返回出去。 4.1 如果找不到,比如访问 /listUser 这个路径就没有在 handle 数组中找到对应,那么就会返回 listUser is not defined. 5. 当访问地址是 /listCategory的时候, 真正的业务函数 requestHandlers.js 中的 listCategory() 就会被调用,并返回业务 Html 代码 : "a lots of categorys". 通过以上的方式,最后就落实在了 requestHandlers.js 的业务代码上面了。 虽然看上去略复杂,但是以后如果要开发新的功能,比如 /listUser, 那么就只需要新增加 listUser 函数,并在 index.js 中对他进行映射即可了。
HOW2J公众号,关注后实时获知最新的教程和优惠活动,谢谢。
问答区域
2024-07-31
router 路由的关键
回答已经提交成功,正在审核。 请于 我的回答 处查看回答记录,谢谢
2021-08-31
JS文件四合一
1 个答案
抱月惊风 跳转到问题位置 答案时间:2021-08-31 handle["/listCategory"] = listCategory(); handle["/listProduct"] = listProduct(); 这两行后面的括号要去掉
回答已经提交成功,正在审核。 请于 我的回答 处查看回答记录,谢谢
2020-07-22
页面错误
2020-06-02
下载了右上角的项目 跑不起来
2020-03-27
db.js的代码有问题
提问太多,页面渲染太慢,为了加快渲染速度,本页最多只显示几条提问。还有 7 条以前的提问,请 点击查看
提问之前请登陆
提问已经提交成功,正在审核。 请于 我的提问 处查看提问记录,谢谢
|