Nodejs笔记1
来源:互联网 发布:ubuntu root用户提权 编辑:程序博客网 时间:2024/06/06 07:27
第一讲
- NodeJs是一个让JavaScript运行在服务端的开发平台;
- Node.js能做什么;
JavaScript是由客户端而生,node.Js为网络而生;
具有复杂的逻辑的网站;
基于社交网络的大web的应用;
web socket服务器
Tcp/Udp套接字应用程序;
命令行工具;
交互式终端程序;
3.异步式I/O与事件驱动;
NodeJs最大的特性就是采用异步式I/O与事件驱动的 架构设计;对于高并发的解决方案,传统的架构是多线程模型,也就是为每个业务逻辑业务提供一个系统线程,通过系统线程切换来弥补同步式I/O调用是的时间开销。Nodejs使用单线程模型,在执行过程中会维护一个事件队列,程序在执行时,在进入时间循环等待下一个事件到来;
第二讲:
- cd nodeDemo
node 进入编译模式; node test.js (Utf8编码需要) - 命令行 node 指令 进入编译模式;
node -v 产看版本号;
node -e eval
node -e “console.log(‘hello’)” - 安装实时调试插件;不用重启了node server.js ,节约了调试时间;
npm -g install supervisor
博客园地址http://www.cnblogs.com/pigtail/archive/2013/01/08/2851056.html
第三讲 : Nodejs 异步式IO与事件式编程
第四讲: 回到函数与事件
异步式读取文件
`// 异步式读取文件 var fs= require('fs'); fs.readFile('app.js','utf-8',function(error,data){ if(error){ console.log( '读取文件失败!'+ error ) }else{ console.log(data + '我是读的文件内容,我是IO操作,我通过事件循环后输出') } });console.log('异步式读取,我是end,我先输出')
`
同步时读取文件
`
// 同步时读取文件var fs = require('fs');var data = fs.readFileSync('test.js','utf-8');console.log('我是同步时读取文件,我先输出'+ data);console.log('我是同步时读取文件,我第二个输出');`
异步式IO把请求发送给了操作系统,然后接着执行后边的语句,执行完毕后,进入事件循环,当fs接收到IO请求弯沉的事件后,事件会主动调用回调函数,完成后续的工作;同步则是阻塞是等待完成后,继续执行;
二. 事件
1. 普通事件的使用
`/* * @Author: Marte * @Date: 2017-04-15 10:25:52 * @Last Modified by: Marte * @Last Modified time: 2017-04-15 10:31:44 */ // 事件 var eventEmitter = require('events').EventEmitter; var event = new eventEmitter(); //注册事件 event.on('some_event',function() { console.log('这是一个自定义的js事件'); }); //触发事件 setTimeout(function(){ event.emit('some_event'); },3000); `
2. NodeJs程序是由事件的循环开始,到事件的循环结束,所有的逻辑都在回调函数中处理;
3. 可以使用emit事件,触发事件;
第五讲: 模块和包
- 什么是模块;
模块和文件是一一对应的.一个Node.js文件就是一个模块,这个文件可能是javascript代码,json或者编译过的C/C++扩展;
var http = require(‘http’),其中http是node.js的一个核心的模块,通过reqire函数获取这个模块,然后使用其中的对象; - 创建和加载模块;
Node.js提供了exports和require两个对象,其中export是模块公开的接口,require用于从外部获取一个模块的接口,即获取模块的export对象;
exports本身是一个普通的空对象,即{} ,它是专门用来声明接口的; 模块使用的一个小案例:
`/*
* @Author: Marte
* @Date: 2017-04-15 12:48:28
* @Last Modified by: Marte
* @Last Modified time: 2017-04-15 12:54:04
*/// 需要导出的方法的类// 声明一个类function Hello(){ var name ; //私有字段 this.setName = function(param){ name = param; }; //方法 this.sayHello = function(){ console.log('Hello' + name); }; //方法}//类定义接口,使得外部可以调用;module.exports = Hello;`
`/*
* @Author: Marte
* @Date: 2017-04-15 12:54:52
* @Last Modified by: Marte
* @Last Modified time: 2017-04-15 12:58:11
*///调用exportDemo中的js类中的方法var hello = require('./exoprtDemo');var he = new hello();he.setName('Peter');he.sayHello();var he2 = new hello();he2.setName('XCL');he2.sayHello();`
- 创建包;
- 包是模块基础上更深一步的抽象,类似于java net的类库,它将某个独立的功能封装起来,用于发布,更新,依赖管理的版本控制,开发了npm来解决包的发布和获取需求;
- 如何创建一个包:
CommonJs规范的包应该是具备以下特征:
package.json必须在包的顶层目录下
二进制文件应该在bin目录下
JavaScript代码应该在lib目录下
文档应该在doc目录下
单元测试应该在test目录下
NodeJs对包要求并没有那么严格,只要顶层目录下有package.json,并符合基本规范即可;
7.package.json的规范
name: 包名,必须是唯一
description:包的简要说明
version:符合语义化版本识别规范的版本字符串
keywords: 关键词数据,通常用于搜索
maintainers: 包维护者,name ,email 可选字段
contributors:贡献者数组,格式月maintainers相同,第一个是作者
bugs: 提交bug的地址,可以是网址或者电子邮件地址;
repoistories: 仓库托管地址数组,每个元素要包含type,url和path字段信息
dependencies : 包的依赖,一个关联数组,由包的名称和版本号组成;
第六讲:包管理器和代码调试
- 如何使用包管理器
Node.js包管理器,即npm是Node.js官方提供的包管理工具,已经成了node.js标准的发布平台,用户node.js包的发布,传播,依赖控制; - 获取一个包;
npm [install/i] [package_name] - 卸载包 : npm uninstall [package_name] [-g]
- 查看包 npm list
- 本地模式和全局模式:
- npm 默认情况下,会从http://npmjs.org 搜索或者下载包,将包安装到当前node_modules
a: 默认是npm install 包名 作为本地模式
b: 全局模式 npm install -g 包名
c: 区别和用法:
因为本地模式不会注册PATH环境变量,npm本地模式仅仅是把包安装到了node_modules子目录下,其中bin目录没有包含在PATH环境变量中,不能直接在命令行中调用;使用全局模式安装的包并不能直接在JavaScript文件中require获得 因为require不会搜索/usr/local/lib/node_modules
通俗讲:当我们要把某个作为项目运行时一部分时候,通过本地模式获取,如果是在命令行下使用,则使用全局模式;
d: 包的发布:
首先确保具备CommonJs为基础包的规范,但与CommonJs并不完全一致,其主要差别在与必填字段的不同,通过使用npm init 可以根据交互式问答产生一个符合标准的package.json
dos进入要添加package.json的目录,npm init 得到执行的文件;在此目录下 npm publish完成发布包;如何更新包;在原来的包的基础上更新 npm publish
如何取消 npm unpublish
发布完成后在 http://search/npmjs.org/
第七讲: 全局对象和全局对象
概念:所有的属性都可以在程序的任何地方访问,即是全局变量。在JavaScript中,通常window是全局对象,而node.js的全局对象时global,所有的全局变量都是global对象的属性,如:console,process等等。
一:全局对象与全局变量
global最根本的作用是作为全局变量的宿主,满足一下条件成为全局变量;
1. 在最外层定义的变量;
2. 全局对象的属性;
3. 隐式定义的变量(未定义直接赋值的变量);
4. 在Node.js中不可能在最外层定义变量,因为素有的用户代码都是属于当前模块的,而模块本身不是最外层的上下文*
二: process
1. 它用于描述当前node.js进程对象,提供了一个与操作系统的简单接口,通常写本地命令行程序的时候,会用到他。
2. Process.argv 是命令行参数数组,第一个元素是node,第二个元素是脚本文件名,第三个元素开始是每个元素是一个运行参数。
3. Process.stdout是标准输出流,通常我们使用的console.log(),其底层是用Process.stdout.write();实现;
4. Process.stdin是标准的输入流,初始时候它是被暂停的。要想从 标准输入流读取数据,必须回复流,并手动编写流的事件响应的函数。
5. Process.nextTick(callback)的功能是为事件循环设置的一项任务。node.js会在下次事件循环调相应的callback,
Node.js适合IO密集型的应用,而不是计算密集型的应用,Process.nextTick()提供了一个这样的工具,可以把复杂的工作拆散,变成较小德尔事件;
Process其他方法:Process.platform(),process.pid(),process.execPath()等方法,参考连接
http://nodejs.org/api/process.html
`/* * @Author: Marte* @Date: 2017-04-16 22:37:52* @Last Modified by: Marte* @Last Modified time: 2017-04-16 22:47:38*///使用process.nextTick使得程序执行速度加快,拆分成小程序//function compute(){ console.log('这是compute类中的方法');}function somethingComplited(args){ console.log('我是somethingComplited类中的方法'); console.log('我是我是somethingComplited类的传入的参数'+args)}//没用使用process.nextTick回调function doSomething(args,callback){ somethingComplited(args); callback();}doSomething('123123',function onEnd(){ compute();});`
运行结果:
我是somethingComplited类中的方法
我是我是somethingComplited类的传入的参数123123
这是compute类中的方法
使用
` /*
* @Author: Marte
* @Date: 2017-04-16 22:37:52
* @Last Modified by: Marte
* @Last Modified time: 2017-04-16 22:54:31
*/
//使用process.nextTick使得程序执行速度加快,拆分成小程序
//
function compute(){ console.log('这是compute类中的方法');}function somethingComplited(args){ console.log('我是somethingComplited类中的方法'); console.log('我是我是somethingComplited类的传入的参数'+args)}//没用使用process.nextTick回调function doSomething(args,callback){ somethingComplited(args); process.nextTick(callback)}doSomething('123123',function onEnd(){ compute();});`
运行结果,同上;
二: console
- console.log()向标准输出流打印字符并以换行符结束
- console.error()标准错苏流输出;
- console.trace()标准错误流输出单签的调用栈;
第八讲: 常用工具util
一,util 全局变量;
1. util.inherits(子类名,父类名)
此方法是一个实现对象间原型继承的函数,JavaScript通过原型赋值来实现继承;
原型继承父类中的方法,子类就可以调用父类中的方法,如下:
`/*
* @Author: Marte
* @Date: 2017-04-16 23:51:12
* @Last Modified by: Marte
* @Last Modified time: 2017-04-17 00:22:02
*/
//演示 子类继承父类 var util = require('util'); //声明一个父类 function Base(){ //声明一个属性 this.name = 'base'; this.base = 2012 ; //声明一个方法 this.sayHello = function(){ console.log('我是父类Base中的声明的字段:' + this.name ) } } //在 类Base原型中赋值一个方法 Base.prototype.showName = function(){ console.log(this.name); } //声明一个子类 function Child(){ this.name = 'child'; } //使用util子类继承父类; util.inherits(Child,Base) //实例一个父类,调用父类中的方法 var base = new Base(); base.showName(); base.sayHello(); console.log(base);//父类 //实例一个子类,尝试调用父类中的方法 var child = new Child(); child.showName(); //child.sayHello();//TypeError: child.sayHello is not a function --所以这里是调用不了的 console.log(child); //子类
`
base
我是父类Base中的声明的字段:base
Base { name: ‘base’, base: 2012, sayHello: [Function] }
child
Child { name: ‘child’ }
util.inspect(object,[showHidden],[depth],[colors])
此方法是一个将任意对象转换为字符串的的方法,通常用于调试和错误输出,它至少接收一个参数Object。
参数: Object ,要转换的对象;
showHidden是一个可选的参数,如果是true,将会输出更多隐藏的信息;
depth:标识最大的递归的层数,如果对象很复杂,可以指定输出的信息的多少,默认是2层,指定为null,打印出来全部;
如果color为true,输出的格式将会一ANSI颜色编码,通常用于在终端显示更漂亮的效果;` var util = require(‘util’);
function Person(){ this.name = 'Peter'; this.toString = function(){ return this.name; }}var obj = new Person();console.log(util.inspect(obj));console.log(util.inspect(obj,true,2,true));`
node执行结果:
Person { name: ‘Peter’, toString: [Function] }
Person {
name: ‘Peter’,
toString:
{ [Function]
[length]: 0,
[name]: ”,
[arguments]: null,
[caller]: null,
[prototype]: { [constructor]: [Circular] } } }
参考文档:http://nodejs.org/api
二、事件驱动events
events是node.js最重要的模板,原因是node.js本身架构就是事件式的,而且它提供了唯一的接口。node.js事件编程的基石,events模块不仅用于用户代码与node.js下层事件循环的交互,还几乎被所有的模块依赖;
1. 事件触发器:
events模块提供了一个对象。events.EventEmitter . EventEmitter的核心就是事件触发和事件监听功能的封装。EventEmitter的每个事件由一个事件或若干个参数组成,事件名是一个字符串,通常表达一定的语义。对于每个事件,EventEmitter支持若干个事件监听器。当事件触发是后,注册到这个事件的事件监听器被依次调用,事件参数作为回调函数参数传递;
常用的api的方法介绍;
1. EventEmitter.on(event,listener)为指定事件注册一个监听器,接收一个字符串event和一个回调函数listener;
2. EventEmitter.emit(event,[arg1],[arg2]…)触发event事件,传递若干可选参数到事件监听器的参数表;
3. EventEmitter.once(event,listener)为指定事件注册一个单次监听器,即监听器最多只会触发一次,触发后立刻解除该监听器;
4. EventEmitter.removeListener(event,listener)移除指定事件的某个监听器。listener必须是该事件已经注册过的监听器;
5. EventEmitter.removeAllListeners([event])移除所有事件的所有监听器,如果指定event则移除指定事件的所有监听器;
2. error事件:
EventEmitter定义了一个特殊的事件error,它包含错误的定义,我们在遇到异常的时候,通常会触发error事件,当error事件触发时候,EventEmitter规定如果没有相应的监听器,node.js会把它当做异常,退出程序并打印调用栈,我们一般要为触发error的事件对象设置监听器,避免遇到错误后整个程序崩溃;
“
3. 继承EventEmitter
大多数时候我们不会直接使用EventEmitter,而是在对象中继承它,包括fs,net,http 在内的。只要是支持事件相应的核心模块的都是EventEmitter的子类;
目的:
1. 具有某个实体功能的对象实现,事件的监听和发射应该是一个对象的发放;
2. javascript的对象机制基于原型,支持部分剁成继承,继承EventEmitter不会打乱独享原有的继承关系 ;
事件案例:
`/*
* @Author: Marte
* @Date: 2017-04-17 23:25:48
* @Last Modified by: Marte
* @Last Modified time: 2017-04-17 23:47:02
*/
//事件监听器 var events = require('events'); //实例化事件对象 var emitter = new events.EventEmitter(); //注册事件监听1 emitter.on('someEvent',function(arg1,arg2){ console.log('事件someEvent的监听事件1',arg1,arg2); }); //注册事件监听2 emitter.on('someEvent', function(arg1,arg2) { console.log('事件someEvent监听器2',arg1,arg2); }); //触发事件 emitter.emit('someEvent','Peter',1991);`
运行结果:
事件someEvent的监听事件1 Peter 1991
事件someEvent监听器2 Peter 1991
第9讲:文件的操作
1.fs模块是文件操作的封装,它提供了文件的读取,写入,更名,删除,遍历目录,底层使用的是POSIX文件操作系统,与其他模块不同,fs模块中所有的操作都提供了异步和同步两个方法。例如 读取文件的内容,异步方法,readFile() ,同步方法readFileSync();
2.fs.readFileSync(fileName,[encoding])
同步读取文件,文件内容会以返回值的形式,返回,如果错误,fs将会抛出异常,需要try和catcha捕获并处理异常;
3. fs对象方法
参考api地址:
http://nodejs.org/api/fs.html
第10节:Http服务器
- Nodejs提供了http模块,其中封装了一个高效的http服务器和一简易的客户端;
- http.server是一个基于事件的http服务器,内部是C++实现,接口有JavaScript封装;
http.request则是一个http客户端工具。用户向服务器发送请求;
一、http服务器;- http.Server实现,它提供了一套封装级别很低的api,仅仅是流控制和简单的解析,所有高层功能都需要他的接口;
- app.js文件:
- http.createServer创建了一个http.Server的实例,将一个函数作为http请求处理函数。这个函数接收两个参数,请求对象request和响应对象response, res显示的写入相应http的状态吗 200等,指定响应头,写入相应体。调用end结束并发送。该实例调用list函数,启动服务器并监听指定的端口号。如:3000端口。
http.ServerRequest请求的信息:
此对象是后端开发者最后在那关注的内容,它一般由http.Server的request事件发送,作为第一 个参数传递,通常简写成request或reg。http请求分为两部分,请求头和请求体。请求内容短的直接放在请求头解析完成后。立即读取,而请求体可能相对内容较长,需要一定的事件传输,因此共提供了三个事件用于控制请求体传输。
(1)。 data:当请求体数据到来时,该事件被触发,该事件一共一个参数chunk,表示接受到的数据。
(2)。 end:当请求数据传输完成时候,该事件被触发,此后,将不会再有数据到来。
(3)。 close:用户当前请求结束是偶,该事件被触发,不同于end,如果用户轻质终止了传输,也为触发close事件。
(4)。 complete:客户端请求是否已经发送完成。5.获取GET请求的内容信息;
由于GEt气球直接被嵌入在路径中,url中?后边的解释get请求参数;Node.js的url模块中的parse函数提供了这个解析函数; 可以直接解析 get参数为对象;- 获取post请求对象。
post请求的内容都在请求体重,http.ServerRequest并没有一个属性内容为请求体,原因是等待请求体传输,可能是一件很耗时的工作,如上传文件,恶意的post请求会消耗服务器的资源,所有nodejs不会解析,请求体,需要的时候,需要手动的来解析;
- 获取post请求对象。
http.ServerResponse返回客户端对象;
决定用户最终能的到的结果,
它是由http.Server的request事件发送的,作为第二个参数传递,一般为response或res
主要有三个函数;
response.writeHead(statusCode,[headers])向请求的客户端发送响应头。
statusCode,http状态码;
header是一个类似数组的对象,表示响应头的每个属性。
response.write(data,[encoding]).向请求的客户端发送响应的内容,data是buffer或者字符串encoding为编码,
response.end([data],[encoding])结束响应,告知用用户所有发送已经完成,当所有返回的内容发送完毕,该函数必须被调用一次,如果不调用,客户端将永远处于等待状态;`/*
* @Author: Marte
* @Date: 2017-04-22 20:45:37
* @Last Modified by: Marte
* @Last Modified time: 2017-04-22 21:00:55
*/
//监听,post请求,监听post请求内容,并将post字符串传转为对象,再将对象打印输出来;var http = require('http');var queryString = require('querystring');var util = require('util');http.createServer(function(requst,response){ var post =''; //注册data事件监听函数,接收每次的请求体的数据,post请求请求的内容可能会很长的字符串 requst.on('data', function(chunk) { post += chunk; }); //注册end事件,请求内容完毕,会触发end事件 requst.on('end', function() { //解析post请求为对象 post=queryString.parse(post); //向前端返回 response.end(util.inspect(post)); });}).listen(3000);console.log("服务器正在监听3000端口")
`
Http客户端
一, http模块提供了两个函数http.request和http.get,功能是作为客户端想http服务器发起请求;
1.http.request(option,callback)发起http请求,option是一个类似关联数组的对象,表示请求的参数。callback是请求的回调函数,option常用的参数如下:
host:请求的域名或ip地址;
port:请求的端口号,默认是80;
method:请求方法,默认是get;
path:请求的根路径,默认是‘/’,QueryString,应该包含在其中,例如/search?name=xcl;
headers:请求头内容 ;
http.request返回一个http.clientRequest的实例;
二, http.get(option,callback)http模块还提供了一个更加简便的方法处理get请求,http.get它是http.request简化版版,唯一的区别是在http.get自动将请求方法设置get请求,同时不需要手动调用req.end();
三, http.ClientRequest。
该对象时有http.request或http.get返回的对象,表示一个已经产生的而且正在进行的http请求,它提供了Response事件,第二个参数指定的回调函数绑定对象,请求必须调用end方法结束请求。
提供函数:
request.abort()终止正在发送的请求,
request.setTimeOut(timeout,[callback])设置请求超时时间,timeout为毫秒数,请求超时后,会调用callback函数;
其他的request.setNoDelay([noDelay]),request.setScoketKeepAlive([enable],[initalDelay])等函数;
参考地址:http://nodejs.org/api/http.html
`/*
* @Author: Marte
* @Date: 2017-04-22 20:45:37
* @Last Modified by: Marte
* @Last Modified time: 2017-04-23 00:27:50
*/
//监听,get请求,演示http请求的流程
var http = require('http'); var queryString = require('querystring'); //启动服务 http.createServer(function(requst,response){ console.log('客户端请求到来,解析参数') var post =''; //注册data事件监听函数,接收每次的请求体的数据,post请求请求的内容可能会很长的字符串 requst.on('data', function(chunk) { post += chunk; }); //注册end事件,请求内容完毕,会触发end事件 requst.on('end', function() { //解析post请求为对象 post=queryString.parse(post); console.log('参数解析完成,返回post请求的name参数') //向前端返回 console.log(post.name) response.end(post.name); }); }).listen(3000); console.log("服务器正在监听3000端口") //创建客户端请求 //1. 客户端请求体内容 var contents=queryString.stringify({ name:'xcl', age:22, address:'beijing' }); //声明请求参数 var options ={ host:'localhost', path:'/', port:3000, method:'post', headers:{ 'Content-Type':'application/x-www-form-urlencoded', 'Content-Length':contents.length } }; //发送请求 var req=http.request(options,function(res){ res.setEncoding('utf-8'); res.on('data',function(data){ console.log('后台接收了请求,并相应给客户端数据,返回数据为'+data) }) }); //发送内容 req.write(contents); //必须调用 request的end事件; req.end();`
执行结果:
服务器正在监听3000端口
客户端请求到来,解析参数
参数解析完成,返回post请求的name参数
xcl
后台接收了请求,并相应给客户端数据,返回数据为xcl
http.get 演示
`/*
* @Author: Marte
* @Date: 2017-04-23 00:37:10
* @Last Modified by: Marte
* @Last Modified time: 2017-04-23 00:50:39
*/
//客户端的 http.get的介绍;var http = require('http');var util = require('util');var url = require('url');//启动服务http.createServer(function(request,response){ console.log('请求到来,开始解析请求参数'); var params = url.parse(request.url,true); console.log('解析完成'); console.log(util.inspect(params)); console.log('向客户端返回数据'); response.end(params.query.name);}).listen(3000);//客户端请求http.get({ host:'localhost', path:'/user?name=peter&age=12', port:3000,},function(response){ response.setEncoding('utf-8'); response.on('data',function(data){ console.log('服务端响应数据为:'+ data); });});`
执行结果:
请求到来,开始解析请求参数
解析完成
Url {
protocol: null,
slashes: null,
auth: null,
host: null,
port: null,
hostname: null,
hash: null,
search: ‘?name=peter&age=12’,
query: { name: ‘peter’, age: ‘12’ },
pathname: ‘/user’,
path: ‘/user?name=peter&age=12’,
href: ‘/user?name=peter&age=12’ }
向客户端返回数据
服务端响应数据为:peter
- nodejs笔记1
- NodeJS 学习笔记1
- NodeJs【自学笔记】1
- nodejs学习笔记1
- nodejs学习笔记1
- nodejs学习笔记1
- Nodejs笔记1
- NodeJs学习笔记1
- nodejs笔记1:问题杂记
- nodejs:Express学习笔记(1)
- nodejs学习笔记(1)
- nodejs学习笔记-1-express
- nodejs笔记
- NodeJS笔记
- nodejs笔记
- nodejs 笔记
- nodeJs 笔记
- NodeJS笔记
- Android Bitmap缩放
- 从国企到阿里的面试经历(一)
- Java 套接字
- matlab基本矩阵操作
- LIS 最长上升子序列问题 O(n^2)
- Nodejs笔记1
- ~求二叉树中最远的两个节点的距离~
- WebLogic和Tomcat浅谈
- 《C语言及程序设计》教学视频 <18 链表中结点的插入和删除> 示例代码
- Android实战技巧:ViewStub的应用
- 用J-Link烧写u-boot到Nor Flash—— 韦东山嵌入式Linux视频学习笔记04
- 全栈——商业目标、用户体验、一专多长
- CodeForces 732 E.Sockets(贪心)
- angular-依赖注入 显示注入/隐式注入