课时69: 提取 router.js 模块01|学习笔记

简介: 快速学习课时69: 提取 router.js 模块01

开发者学堂课程【Node.js 入门与实战课时69: 提取 router.js 模块01】学习笔记,与课程紧密联系,让用户快速学习知识

课程地址https://developer.aliyun.com/learning/course/588/detail/8304


课时69: 提取 router.js 模块01

 

1、路由模块负责路由判断单独提取一个路由模块

2、新建一个js文件文件名叫router.js用来保存路由

//该模块负责封装所有路由判断代码

3、根据这三个步骤进行思考:

(1)思考,该模块中要封装什么代码

封装以下代码

//先根据用户请求的路径(路由) ,将对应的HTML页面显示出来

if (req. pathname ·=== '/'·| |· req.pathname ·=== ' /index' ·&&· req.method·===' get')· {

// 1.读取data.json 文件中的数据,并将读取到的数据转换为list 数组

readNewsData(function(list) {

// 2.在服务器端使用模板引擎,将list 中的数据和 index. html文件中的内容结合渲染给客户端

res . render(path. join(__ dirname, 'views' ,' index.html'), { list: list });

});

} else if ·(req.url ·=== . ‘/submit'· && req. Method·=== ' get') {

//读取 submit.html 并返回

res. render(path. join(__ dirname, 'views' ,' submit. html' ));

} else if· (req. pathname === ' /item' && req . method == ' get ' ) {

// 1.获取当前用户请求的新闻的id

// url0bj .query. id

// 2.读取data.json 文件中的数据,根据id找到对应新闻

readNewsData(function(list_ news) {

var model = null ;

//循环list_news中的数据,找到和id值相等的数据

for (var i - 0; i < list_ news.length; i++) {

//判断集合中是否有与用户提交的id相等的新闻

if (list_ news[i]. id. toString() === req. query.id) {

//如果找到了相等的新闻,则将其记录下来

model = list_ news[i];

break;

}

}

if. (model)·f

// 3.调用res. render() 函数进行模板引擎的渲染

res . render(path. join(__ dirname,' 'views' ,' details.html'),f item:model ]);

}else{

res .end('No Such Item');

}

});

}else if (req .pathname === ’. /add' && req . method ===‘get'){

// 1.读取data.json 文件的数据

readNewsData(function(list) {

//2.

//在把新闻添加到list之前,为新闻增加一个id属性

req. query.id . list. length;

//向数组对象list中push一条新闻

list . push(req . query);

// 3.写入data.json 文件

writeNewsData(JSON. stringify(list), function() {

//重定向

res . statusCode = 302 ;

res . statusMessage = Found' ;

res. setHeader('Location', '/');

res. end();

});

});

}else if-(req.url ===’ /add' && . req. method . ==='post'){

//1. 读取data. json

readNewsData(function(list){

//2. 读取用户 post提交的数据

postBodyData(req, function(postData){

//3.为用户提交的新闻增加一个id属性,并且把新闻对象push 到list中

postData.id = list. length;

list . push(postData);

// 4.将新的list数组,在写入到data.json 文件中

writeNewsData(JSON. stringify(list), function() {

//重定向

res . statusCode =302 ;

res . statusMessage = " Found' ;

res. setHeader('Location' , '/');

res. end();

});

});

});

}else if (req . url. startsWith( '/resources') && req. method ==='get') {

//如果用户请求是以/resources 开头,并且是get请求,就认为用户是要请求静态资源

// /resources/images/s. gif

res . render(path. join(__ dirname, req. url));

}else {

res .writeHead(404, "Not Found', {

content-type : text/html; charset=utf-8’

});

res .end( '404, Page Not Found.');

}

(2)思考,这些代码有用到外部的数据吗如果用到了,是否需要通过参数将这些数据传递到当前模块中

有用到reqres把当前router.js暴露给一个函数通过这个函数可以把它们传过来

Module.exports=function(req,res){

//body·····

};

既然现在router.js对外暴露给函数在主模块中加载输入var router=require(‘./router.js‘);加载完毕之后Module.exports=function(req,res){

};

返回的是一个函数主模块中router也是一个函数接着输入

//调用路由模块的返回值函数),并将req和res对象传递给router.js模块

Routerreqres);

这样通过路由可以把req和res传递给exports模块将封装的代码剪切粘贴到//body·····位置就可以把主模块包含的代码删掉目前在主模块里面调用了contextreqres和routerreqres两个函数

梳理以下代码

if (req. pathname ·=== '/'·| |· req.pathname ·=== ' /index' ·&&· req.method·===' get')· {

readNewsData(function(list) {

首先做了路由判断路由判断里面有业务代码readNewsData这个函数是在index.js里面被封装的为了程序暂时可以运行将函数拷贝到router.js,下面封装的函数在index.js里面没有用因为这些函数是在处理业务时采用index.js里面没有业务可以处理所以这些函数就用不到拷贝到rouder.js

//封装一个读取data.json 文件的函数

function , readNewsData(callback){

fs. readFile(path. join(__ dirname,·'data' , ‘data. json'),' 'utf8', · function(err, data){

if. (err-&& err. code . !==. " ENOENT'){

throw- err;

}

var . list . =. JSON parse(data | |·'[]');

//通过调用回掉函数callback()将读取到的数据list,传递出去. callback(list);

});

}

//封装一个写入data.json 文件的函数

function writeNewsData(data, callback) {

fs .writeFile(path. join(_ dirname,’data ' , data. json' ), data, function(err) {

if (err) {

throw err;

}

//调用callback() 来执行当写入数据完毕后的操作

Callback();

}};

}

//封装一个获取用户post提成的数据的方法

Function postbodydatareqcallback){

Var array =[];

Req.on(‘data’,function(chunk){

Array.push(chunk);

});

//监听request 对象的end事件

//当end事件被触发的时候表示上所有数据都已经提交完毕了

Req.on(‘end’function(){

var postBody =Buffer . concat( array);

//把获取到的buffer对象转换为一个字符串

postBody = postBody . toString( 'utf8' );

//把post请求的查询字符串,转换为一个json对象

postBody = querystring. parse (postBody);

//把用户post提交过来的数据传递出去

Callbackpostbody);

});

}

回到index.js可以发现主模块使用服务加载var router=require(‘./router.js‘)和var context=require(‘./context.js‘),fs模块path模块mime模块等都可以删掉在这里只需要加载http模块创建服务启动服务在用户的req事件里面先调用context模块对reqres进行扩展再调用router模块进行目标判断现在的index.js的代码如下

//1. 加载http模块

Var ,http· =". require( 'http');

var , context .= require(' ./context.js' );

var , router . =. require(' ./router . js');

// 2.创建服务

http. createServer(function(req, ·res) f

//调用context.js模块的返回值函数),并将req和res对象传递给context.js模块

context(req, res);

//调用路由模块的返回值(函数),并将req和res对象传递给router.js 模块

router(req, res);

})listen(9090, function() {

console . log( 'http://localhost:9090');

});

(3)当前模块对外需要暴露的东西(module.exports的值)

4、在router.js里面格式化一下首先路由判断req,if(req. Pathname===‘/’||req. Pathname ===‘index’&&req . method

===get' ){

调用 rednewsdata 封装调用 res.render注意正式在 context 模块中为res增加了一个render函数所以render函数无论在任何一个模块中只要能拿到res对象就可以用它

5、//封装一个写入data.json 文件的函数

function writeNewsData(data, callback) {

fs .writeFile(path. join(_ dirname,’data ' , data. json' ), data, function(err) {

if (err) {

throw err;

}

//调用callback() 来执行当写入数据完毕后的操作

Callback();

}};

}

//把post请求的查询字符串,转换为一个json对象

postBody = querystring. parse (postBody);

这里fs模块和path模块querystring模块需要加载

var fs = require('fs');

var path =require(' path');

var querystring =require( ‘querystring ’); 

这样在主模块中启动服务调用context测试过没问题再调用路由模块路由模块中做了路由判断并做了业务处理现在测试一下是否有问题启动没问题列表可以显示详情可以显示新闻可以添加证明现在封装路由模块提取的第一步没有问题但是路由模块里面它不光负责路由判断还做很多业务处理业务处理代码不应该放到路由模块里路由模块职责非常单一就是做路由判断业务处理代码要放到业务模块里接下来再提取业务模块

相关文章
|
2月前
|
缓存 JSON JavaScript
Node.js模块系统
10月更文挑战第4天
43 2
|
3月前
|
JavaScript 前端开发 API
Vue学习笔记3:对比纯JavaScript和Vue实现数据更新的实时视图显示
Vue学习笔记3:对比纯JavaScript和Vue实现数据更新的实时视图显示
|
2月前
|
JavaScript 应用服务中间件 Apache
Node.js Web 模块
10月更文挑战第7天
33 0
|
2月前
|
JavaScript 网络协议
Node.js 工具模块
10月更文挑战第7天
21 0
|
4月前
|
JavaScript 数据可视化
JS如何优雅的实现模块自动滚动展示
【8月更文挑战第22天】JS如何优雅的实现模块自动滚动展示
46 1
JS如何优雅的实现模块自动滚动展示
|
2月前
|
JavaScript 前端开发
【干货分享】JavaScript学习笔记分享
【干货分享】JavaScript学习笔记分享
58 0
|
3月前
|
Web App开发 前端开发 JavaScript
HTML/CSS/JS学习笔记 Day3(HTML--网页标签 下)
HTML/CSS/JS学习笔记 Day3(HTML--网页标签 下)
|
2月前
|
JavaScript 前端开发 应用服务中间件
Node.js Web 模块
Node.js Web 模块
|
3月前
Nest.js 实战 (十二):优雅地使用事件发布/订阅模块 Event Emitter
这篇文章介绍了在Nest.js构建应用时,如何通过事件/发布-订阅模式使应用程序更健壮、灵活、易于扩展,并简化服务间通信。文章主要围绕@nestjs/event-emitter模块展开,这是一个基于eventemitter2库的社区模块,提供了事件发布/订阅功能,使得实现事件驱动架构变得简单。文章还介绍了如何使用该模块,包括安装依赖、初始化模块、注册EventEmitterModule、使用装饰器简化监听等。最后总结,集成@nestjs/event-emitter模块可以提升应用程序的事件驱动能力,构建出更为松耦合、易扩展且高度灵活的系统架构,是构建现代、响应迅速且具有高度解耦特性的Nest.
|
3月前
|
缓存 JavaScript 前端开发
JavaScript模块化开发:ES6模块与CommonJs的对比与应用
JavaScript模块化开发:ES6模块与CommonJs的对比与应用
34 2