zhuhuiwen Front-end Dev Engineer

nodejs-day04

2017-01-16

异步io模块、中间件、路由

url模块

  • 如果传入第二个参数为true,则url模块解析后的对象的query属性是一个对象了
    • 把浏览器传过来的参数转换成对象
  • 代码

	var urlObj = url.parse(req.url,true);
	urlObj.query--->对象

request通过data事件和end事件来接收post的数据

  • 代码

	req.on('end',function(){
		//处理请求
		res.end('成功');//放在里面,是因为通过会先被执行,所以不好进行放在外面
	})

同步和异步

  • 同步会阻塞后面的代码
  • 异步则不会
    • 异步中有嵌套才具有先后顺序

异步io模型

异步非i/o操作和异步i/o操作

  • 异步非io
    • setTimeout和setInterval
  • 异步io操作
    • 操作文件和网络操作和fs
  • 图解1 event-loop
  • 代码执行殊顺序
    • 主线程
      • 执行
        • node运行大概三类 同步和异步(io、分io)
        • 执行同步,绕圈
        • 顺序执行
          • 遇到见io,找子线程
          • 自己继续执行,出现异步非io,主线程执行
        • 子线程执行完成,主线程多callback
          • callback是同步自己执行,异步子线程执行
        • 整个代码执行完成
    • 子线程
      • 拿到异步io代码,执行
      • 完成后,交给主线程,自己去线程池
  • 总结
    • node去执行一段代码,里面包含同步、异步io、异步非io
    • node出一个主线程,去轮询代码
    • 先去执行所有的同步代码,执行完成之后,继续轮询
    • 对于异步非io/异步io,先遇见谁就先执行哪个
      • 如果先遇到异步非io,就主线程自己去执行
      • 在异步非io中,如果符合条件,就将这个异步非io的回调放到队列的尾部
      • 继续轮询
    • 下面的异步io会去执行吗
      • 就是不会阻塞代码的执行
    • 异步io开一个子线程,给主线程一个反馈,将回调在队列中
    • 主线程进行轮询,看callback….重新从第一个执行…轮询

    • 异步非io,主线程会把回调扔回到队列里面来
  • 图解2 event-loop
  • 代码
    • 从js走,将需要执行的任务放在队列中
    • 一行一行执行
      • 主线程先将队列中的代码都先执行完
      • 继续轮询
        • 里面的异步代码
        • 如果是异步io,拉一个子线程进行
      • 继续轮询
        • 遇到异步非io,只是个计时器,满足条件
        • 满足条件
          • 执行callback到队列中
        • 不满足条件
          • 继续轮询
        • 遇到异步io
          • 继续拉子线程
        • 子线程完成后,将callback扔回队列的尾部
        • 主线程轮询
          • 看callback中是不是同异步
          • ….
        • 出现的问题
          • callback里面有什么代码
            • 有同步和异步非io和要不非io…
            • 注意:
              • 是什么
          • 回调函数里面
            • 是同步还是异步的
              • 同步的
              • 回调函数里面,也是这一个主线程来控制的吗????
                • 只有一个主线程
              • 异步要有顺序,是一层嵌套一层

异步和多线程的比较

  • node的异步就是通过异步处理的方式替你去完成多线程的编程
  • 比较
    • 多线程编程更加灵活
    • 异步使用起来更加简单(node帮你去做的)
    • node擅长io操作
      • 不擅长cpu密集型—>大量的计算,计算是同步,现在
      • 规避for循环

express

区别一个什么是框架,什么是类库

  • 类库和框架
    • 类库
      • 类库是你调用他的方法
    • 框架
      • 框架提供了一套规范,你按照这套规范写,框架再来运行你写的代码

express

  • 网站
    • www.expressjs.com.cn

express-generator脚手架工具

  • 命令
    • npm install -g express-generator
  • 作用
    • 帮助我们快速构建网站的
  • 脚手架构建项目的目录结构
    • app.js
    • package.json
    • bin是配置文件
    • node_modules引入的包
      • 其实不用新建的,直接进行npm install
    • public
      • 放置静态的文件的资源
    • routes
      • 放置路由的
    • views
      • 存放模板引擎文件的
      • 前端有模板引擎,后端也有模板引擎

为什么使用框架?

app.use(express.static(path.join(__dirname, 'public'))); - 原生Node开发,会发现很多问题。比如:   + 呈递静态页面很不方便,需要处理每个HTTP请求   + 路由处理不直观清晰,需要写很多字符串判断和正则表达式   + 不能集中精力写业务,要考虑很多其它的东西 - Express框架致力于解决上述问题。 - 例如,jQuery,简化了dom操作,让我们的关注点从如何去操作dom转变成具体我们要操作dom去干什么。

使用express构建的第一个程序

  • 项目开发流程
    • 安装脚手架工具
      • npm install -g express-generator
    • 控制台上打命令
      • express 或者 express 加上项目名
    • 执行npm install
      • 加载package.json中的依赖node_module
    • 进行写入口文件app.js
  • 入口文件代码基本步骤
    • 引入express模块
    • 引入path模块
      • path是一个核心模块,拼接路径的
    • var app = express();//也就是类似于创建一个server
    • express.static(root, [options])
      • 参数
        • root 参数指的是静态资源文件所在的根目录
      • express.static 是 Express 内置的唯一一个中间件。
      • 负责托管 Express 应用内的静态资源。
    • 下面的代码就是将public目录下的代码托管给express.static
    • app.use就是将托管的页面进行挂在在app这个服务上
  • 代码

	/*
	  1. 在项目目录下执行express,进行生成目录结构
	  2. 执行npm install,使用npm下载node_module,就是package.json中的dependencies
	  3. 写入口文件,就是这个app.js
	*/
	// 创建一个 Express 应用。
	//express() 是一个由 express 模块导出的入口(top-level)函数。
	
	var express = require('express');
	var path = require('path');
	var app = express();//也就是类似于创建一个server
	/*
	express.static(root, [options])
	  - 参数
	    root 参数指的是静态资源文件所在的根目录
	
	express.static 是 Express 内置的唯一一个中间件。
	负责托管 Express 应用内的静态资源。
	下面的代码就是将public目录下的代码托管给express.static
	
	app.use就是将托管的页面进行挂在在app这个服务上
	*/
	app.use(express.static(path.join(__dirname,'public')));
	
	app.listen(3000);

路由

  • 概念
    • 路由器
      • 是告知请求者,所请求的ip在哪里,并且把信息发送过去
    • web框架的路由
      • 是告知框架,所请求的http参数应该调用的模块、类、方法在哪里,把请求发送过去
  • 部分代码
    • 上部分代码在express中构建的第一个程序中
    • 代码
	
	/* 
	  app.get(path, callback [, callback ...])
	  HTTP GET请求路由到指定的路径与指定的回调函数
	*/
	app.get('/getData',function(req,res){
	   res.send('----GET request to homepage---');
	   res.end();
	});
	/*
	app.post(path, callback [, callback ...])
	HTTP POST请求路由到指定的路径与指定的回调函数
	*/
	app.post('/getData',function(req,res){
	  res.send('---POST request to homepage---');
	  res.end();
	})

通过模糊匹配路由

  • js模糊匹配
    • 当路径当中有一个字符我不记得存不存在了,在这个字符后面使用“?”
      • /apples? apples 和 apple
    • 当路径中有n个字符我不记得了,用()将这些字符包裹起来再在后面加“?”
      • /get(New)? getNew或是get
    • 当我们不记得一个字符出现了多少次
      • /go+gle o出现一次或是一次以上
    • 当请求中,需要将一部分字符模糊匹配的时候用*
      • /b*u bu或是b…u
    • 使用正则
      • /a/ 只有a可以访问
      • /.*fly$/看是不是.fly结尾的
  • 代码


	/*
	js模糊匹配
	  1. 当路径当中有一个字符我不记得存不存在了,在这个字符后面使用“?”
	      /apples?    apples   和 apple
	  2. 当路径中有n个字符我不记得了,用()将这些字符包裹起来再在后面加“?”
	      /get(New)?   getNew或是get
	  3. 当我们不记得一个字符出现了多少次
	      /go+gle    o出现一次或是一次以上
	  4. 当请求中,需要将一部分字符模糊匹配的时候用*
	      /b*u  bu或是b...u
	  5. 使用正则
	    5.1 /a/  只有a可以访问
	    5.2 /.*fly$/看是不是.fly结尾的
	*/
	
	app.get('/apples?',function(req,res){
	  res.end('apple或是apples');
	});
	app.get('/get(New)?',function(req,res){
	  res.end('getNew或是get');
	});
	app.get('/go+gle',function(req,res){
	  res.end('go....gle,0是一个及其以上');
	});
	app.get('/b*u',function(req,res){
	  res.end('bu或是b...u');
	});
	app.get('/a/',function(req,res){
	  res.end('接口地址就是a,只有a可以访问');
	});
	
	app.get('/.fly$/',function(req,res){
	  res.end('以.fly结尾的');
	})

中间件

什么是中间件?

  • 通过 app.use(中间件的代码)使用中间件
  • Express 是一个自身功能极简,
    • 完全是由路由和中间件构成一个的 web 开发框架
    • 从本质上来说,一个 Express 应用就是在调用各种中间件
  • 中间件(Middleware)是一个函数,
    • 它可以访问请求对象(request object (req)), 响应对象(response object (res)),
    • 和 web 应用中处于请求-响应循环流程中的中间件,
    • 一般被命名为 next 的变量。
  • 往往一个http请求发送到服务器,都需要通过很多的判断和处理。
    • 一个请求发送过来—->用户是否已经登录—->用户请求的是什么资源(静态资源、动态页面、json数据)
    • —->统计一下用户的请求—>(如果请求的内容不存在)返回404

中间件的功能

  • 中间件的功能包括
    • 执行任何代码
    • 修改请求和响应对象
    • 终结请求-响应循环
    • 调用堆栈中的下一个中间件
    • 如果当前中间件没有终结请求-响应循环
      • 则必须调用 next() 方法将控制权交给下一个中间件,否则请求就会挂起。

中间件种类

  • Express 应用可使用如下几种中间件:
    • 内置中间件
    • 第三方中间件
      • 错误处理中间件
      • 应用级中间件
      • 路由级中间件

使用中间件

  • 使用use进行将中间件挂在在app服务上
  • app.use(写一个中间件)
    • 两个参数
      • 第一个参数路径,可选
      • 第二个采纳数,回调函数
        • 三个参数
          • req
          • res
          • next
            • 注意:
              • next是一个方法,被调用后,继续走下一个中间件

使用中间件的示例代码

  • app.use(中间件),将中间件进行挂在到app上
    • app.use(中间件的回调函数)
      • 回调函数中的参数
        • req 请求对象
        • res 响应对象
        • next 下一个执行的中间件

		//引入express和path
		var express = require('express');
		var path = require('path');
		var app = express();//创建一个服务
		//通过express.static将public成静态目录托管给express
		//再将静态目录挂在到app上
		app.use(express.static(path.join(__dirname,'public')));
		
		//app.use(中间件),将中间件进行挂在到app上
		/**
		 * app.use(中间件的回调函数)
		 *  回调函数中的参数
		 *    1.  req  请求对象
		 *    2.  res  响应对象
		 *    3. next  下一个执行的中间件
		 */
		app.use(function(req,res,next){
		    var cookie = false;
		    if(cookie){
		      res.send('返回的数据');
		      res.end('登录成功');
		      next();
		    }else{
		      //这边不登录成,下面的中间件就不会执行了,没写next()
		      res.end('请重新登录');
		    }
		});
		
		app.use(function(req,res,next){
		    console.log('这是第二个执行的中间件');
		    res.end('这是第二个执行的中间件');
		});
		
		app.listen(3000);

总结

  1. 路由
    1. 通过一种并联的结构,让你的请求找到唯一对应处理
  2. 中间件
    1. 通过串联的形式,把一堆过滤器进行串联起来

path.join

  • path.join([…paths])
    • 通过path模块的join方法去拼接多个字符串,输出一个正确的路径给你
    • console.log(path.join(__dirname,’./test.txt’));
      • 拼成一个绝对路径
  • 其他的方法看这个代码

	var fs = require('fs');
	var path = require('path');
	//取文件名 myfile.html
	var bsn = path.basename('C:\\temp\\myfile.html');
	console.log(bsn);
	
	//取路径中的文件夹路径部分 C:\\temp
	var dirn = path.dirname('C:\\temp\\myfile.html');
	console.log(dirn);
	
	//获取文件的后缀名 .html
	var extn = path.extname('index.html');
	console.log(extn);
	
	/*path.join([...paths])
	通过path模块的join方法去拼接多个字符串,输出一个正确的路径给你*/
	console.log(path.join(__dirname,'./test.txt'));
	
	fs.readFile(path.join(__dirname,'./test.txt'),'utf8',function(err,data){
	    if(err){
	        console.log(err);
	        return;
	    }
	    console.log(data);
	})

postman插件

  • 安装chrome插件的第二种方法
    • 拖到_meta…进行将前面的_去掉
    • 就变成插件文件了
    • 直接将文件夹拖到chrome插件中就好了
    • 谷歌插件破解方式

Similar Posts

上一篇 nodejs-day03

下一篇 chrome插件总结

Comments