一、创建第一个简单应用
1.创建服务器(在当前目录下新建server.js)
var http = require('http');http.createServer(function(request,response){ //发送http头部 //http请求值状态:200OK //内容类型:text/plain response.writeHead(200,{'Content-Type':'text/plain'}); //发送响应数据 helloword response.end('hello word\n'); }).listen(8888);//端口8888console.log('Server running at http://127.0.0.1:8888/');
2.打开打开浏览器访问 :8888/查看状态
浏览器中响应helloword及创建成功
二、npm的使用
(说明)
-允许用户从NPM服务器下载别人编写的第三方包到本地使用。-允许用户从NPM服务器下载并安装别人编写的命令行程序到本地使用。-允许用户将自己编写的包或命令行程序上传到NPM服务器供别人使用。(查看是否安装)
$ node -v
(npm旧版本升级)
$npm install npm -g
(使用 npm 命令安装模块)
$ npm install比如安装node的框架模块$ npm install express安装好之后,express 包就放在了工程目录下的 node_modules 目录中,因此在代码中只需要通过 require('express') 的方式就好,无需指定第三方包路径。var express = require('express');
- 卸载模块(
$ npm uninstall express
) - 更新模块(
$ npm update express
) - 搜索模块(
$ npm search express
) - 创建模块(
$ npm create express
)
三、Node.js REPL(交互式解释器)
Node 自带了交互式解释器,可以执行以下任务: 读取 - 读取用户输入,解析输入了Javascript 数据结构并存储在内存中。 执行 - 执行输入的数据结构 打印 - 输出结果 循环 - 循环操作以上步骤直到用户两次按下 ctrl-c 按钮退出。 Node 的交互式解释器可以很好的调试 Javascript 代码。
输入 $ node
命令即可
表达式运算
$ node
1 +4 5 5 / 2 2.5 3 * 6 18 4 - 1 3 1 + ( 2 * 3 ) - 4 3
下划线(_)变量
你可以使用下划线(_)获取表达式的运算结果: $ node
var x = 10 undefined var y = 20 undefined x + y 30 var sum = _ undefined console.log(sum) 30 undefined
四、pepl命令
ctrl + c
- 退出当前终端。ctrl + c
按下两次 - 退出 Node REPL。ctrl + d
- 退出 Node REPL. 向上/向下 键 - 查看输入的历史命令 tab 键 - 列出当前命令 .help - 列出使用命令 .break - 退出多行表达式.clear
- 退出多行表达式.save filename
- 保存当前的 Node REPL 会话到指定文件.load filename
- 载入当前 Node REPL 会话的文件内容。
五、Node.js回调函数
Node 使用了大量的回调函数,Node 所有 API 都支持回调函数。 例如,我们可以一边读取文件,一边执行其他命令,在文件读取完成后,我们将文件内容作为回调函数的参数返回。这样在执行代码时就没有阻塞或等待文件 I/O 操作。这就大大提高了 Node.js 的性能,可以处理大量的并发请求。
阻塞代码实例(同步执行):
-创建txt文件作为读取文件a.txt。-创建main.js文件,代码如下:var fs = require('fs');//引入fs模块var data = fs.readFileSync("a.txt");console.log(data.toString());console.log("end");
非阻塞代码实例(异步执行):
-var fs = require("fs");//引入fs模块fs.readFile("a.txt",function(err,data){ if(err){ return console.error(err); }console.log(data.toString())})console.log("end");
六、事件循环
实例:
创建main.js文件代码://引入events模块var events = require("events");//创建eventEmitter对象Var eventEmitter = new events.EventEmitter();//创建事件处理程序
var connectHandler = function conected(){console.log("connect ok");//触发data_received 事件eventEmitter.emit("data_received");
}
//绑定connection事件处理程序
eventEimtter.on('connection',connectHandler);// 使用匿名函数绑定 data_received 事件
eventEmitter.on('data_received', function(){ console.log('数据接收成功。');});// 触发 connection 事件
eventEmitter.emit('connection');console.log("end!");
七、Node.js EventEmitter
Node.js 所有的异步 I/O 操作在完成时都会发送一个事件到事件队列。
Node.js里面的许多对象都会分发事件:一个net.Server对象会在每次有新连接时分发一个事件,一个fs.readStream对象会在文件被打开的时候发出一个事件。 所有这些产生事件的对象都是 events.EventEmitter的实例。events 模块只提供了一个对象: events.EventEmitter。EventEmitter 的核心就是事件触发与事件监听器功能的封装。你可以通过require("events");来访问该模块。
//引入events模块var events = require("events");//创建EventEmitter对象var eventEmitter = new events.EventEmiter();
EventEmitter 对象如果在实例化时发生错误,会触发 error 事件。当添加新的监听器时,newListener 事件会触发,当监听器被移除时,removeListener 事件被触发。
EventEmitter简单介绍
在Nodejs中,异步的I/O 操作在完成时会触发事件队列中的具体事件。这里的主要原因是这些对象本质上是通过继承EventEmitter来实现对事件的处理和回调,如文件的file读写等。(这里的事件与DOM树上事件不同,不存在事件冒泡和捕获的情况。)我们也可以让自定义的对象通过继承EventEmitter来让其走观察者模式(事件监听与触发),主要通过EventEmitter的on和emit这些方法来构成。也有更为具体的API。如emitter.once(event,listener)添加一次性 listener(这个 listener 只会被触发一次,触发完成后就被删除)。
我们用一个简单的例子说明 EventEmitter 的用法:
events.js文件
//EventEmitter是events模块中的一个对象。var EventEmitter = require('events').EventEmitter;//实例化一个eventEmittervar event = new EventEmitter();//绑定个自定义事件,即回调函数event.on('some_event',function(){ console.log('some_event事件触发');})//3s后通过emit触发这个事件。setTimout(function(){ event.emit('some_event');},3000);
大致流程:
引用events包-->调用EventEmitter包-->实例化-->绑定自定义事件-->emit触发事件运行这段代码,1 秒后控制台输出了 'some_event 事件触发'。其原理是 event 对象注册了事件 some_event 的一个监听器,然后我们通过 setTimeout 在 3000 毫秒以后向 event 对象发送事件 some_event,此时会调用some_event 的监听器。
EventEmitter主要API
emitter.on('event',listener)//注册一个事件
emitter.once('event',listener)//注册一个一次性事件,触发后即销毁。emitter.removeListener(event, listener) 在时间队列中移除某一个事件。emitter.removeAllListeners([event]) 删除整个事件队列,或多个事件。emitter.listeners(event) 返回某些事件 emitter.emit(event, [arg1], [arg2], […]) 触发事件,可传入具体参数八、Buffer(缓冲区)
JavaScript 语言自身只有字符串数据类型,没有二进制数据类型。 但在处理像TCP流或文件流时,必须使用到二进制数据。因此在 Node.js中,定义了一个 Buffer 类,该类用来创建一个专门存放二进制数据的缓存区。 在 Node.js 中,Buffer 类是随 Node 内核一起发布的核心库。Buffer 库为 Node.js 带来了一种存储原始数据的方法,可以让 Node.js 处理二进制数据,每当需要在 Node.js 中处理I/O操作中移动的数据时,就有可能使用 Buffer 库。原始数据存储在 Buffer 类的实例中。一个 Buffer 类似于一个整数数组,但它对应于 V8 堆内存之外的一块原始内存。
创建buffer类
实例:
创建长度为10字节的buffer实例var buf = new Buffer(10);通过数组创建buffer实例
var buf= new Buffer([1,2,3,4,5]);通过字符串来创建buffer实例
var buf = new Buffer('www.lipengpeng.com',"utf-8");写入缓冲区
buf.write(string[, offset[, length]][, encoding]);
参数 参数描述如下: string - 写入缓冲区的字符串。 offset - 缓冲区开始写入的索引值,默认为 0 。 length -写入的字节数,默认为 buffer.length encoding - 使用的编码。默认为 'utf8' 。 返回值.返回实际写入的大小。如果 buffer 空间不足, 则只会写入部分字符串。
实例:
var buff = new Buffer(15);var len = buff.write('lipengpeng.com');console.log(len);//返回写入的大小 result:14
缓冲区读取数据
读取node缓冲区语法:
buf.toString([encoding[,start[,end]]]);
参数:
参数描述如下:- encoding - 使用的编码。默认为 'utf8' 。
- start - 指定开始读取的索引位置,默认为 0。
- end -结束位置,默认为缓冲区的末尾。
返回值
解码缓冲区数据并使用指定的编码返回字符串。实例:buf = new Buffer(26);for (var i = 0 ; i < 26 ; i++) { buf[i] = i + 97;}console.log( buf.toString('ascii')) // 输出: abcdefghijklmnopqrstuvwxyzconsole.log( buf.toString('ascii',0,5)); // 输出: abcdeconsole.log( buf.toString('utf8',0,5));// 输出: abcdeconsole.log( buf.toString(undefined,0,5));// 使用 'utf8' 编码,并输出: abcde
将buffer转为json对象
语法
将node buffer转为json对象语法格式buff.toJSON()//fanhui json对象实例:var buff = new Buffer("www.lipengpeng.com");var json = buff.toJSON(json);结果:{ type: 'Buffer',data:[ 119, 119,119, 46,108, 105, 112, 101, 110, 103, 112, 101, 110,103,46,99,111,109 ] }
缓冲区合并
Buffer.concat(list[, totalLength])
参数: list - 用于合并的 Buffer 对象数组列表。 totalLength - 指定合并后Buffer对象的总长度。 返回值: 返回一个多个成员合并的新 Buffer 对象。
实例:
var buffer1 = new Buffer('www. ');var buffer2 = new Buffer('lipengpeng.com');var buffer3 = Buffer.concat([buffer1,buffer2]);console.log("buffer3 内容: " + buffer3.toString());
缓冲区比较
buf.compare(otherBuffer); 参数:otherBuffer - 与 buf 对象比较的另外一个 Buffer 对象。
返回一个数字,表示 buf 在 otherBuffer 之前,之后或相同。var buffer1 = new Buffer('ABC');var buffer2 = new Buffer('ABCD');var result = buffer1.compare(buffer2);if(result < 0) { console.log(buffer1 + " 在 " + buffer2 + "之前");}else if(result == 0){ console.log(buffer1 + " 与 " + buffer2 + "相同");}else { console.log(buffer1 + " 在 " + buffer2 + "之后");}
拷贝缓冲区
buf.copy(targetBuffer[, targetStart[, sourceStart[, sourceEnd]]]);
参数描述如下:targetBuffer - 要拷贝的 Buffer 对象。 targetStart - 数字, 可选, 默认: 0 sourceStart - 数字, 可选, 默认: 0 sourceEnd - 数字, 可选, 默认: buffer.length
实例
var buffer1 = new Buffer('ABC');//拷贝一个缓冲区var buffer2 = new Buffer(3);buffer1.copy(buffer2);九、Steam流
Node.js,Stream 有四种流类型:
- Readable - 可读操作。
- Writable - 可写操作。
- Duplex - 可读可写操作.
- Transform - 操作被写入数据,然后读出结果。
所有的 Stream 对象都是 EventEmitter 的实例。常用的事件有:
- data - 当有数据可读时触发。
- end - 没有更多的数据可读时触发。
- error - 在接收和写入过程中发生错误时触发。
- finish - 所有数据已被写入到底层系统时触发。
实例:流中读取数据
创建一个txt文件 test.txt
创建js文件,main.jsvar datas='';//fs模块用于对系统文件及目录进行读写操作var fs = require('fs');//创建可读流var readerStream = fs.createReaderStream(test.txt');//如文件中有中文字符请设置编码readerStream.setEncoding('utf8');//处理事件流readerStream.on('data',function(res){ data+=res; console.log(data)});
实例:写入流
var fs = require('fs'); var data="lipengpeng.com"; //创建一个可写入的流,写入到文件write.txt; var writerStream = fs.createWriteStream('write.txt'); //使用utf_8写入数据 writerStream.write(data,'utf8'); // 标记文件末尾 writerStream.end(); writerStream.on('finish', function() { console.log("ok"); });
实例:复制流
var fs = require('fs'); //写入流 var writerStream = fs.createWriteStream('write.txt'); //读取流 var readerStream = fs.createReadStream('read.txt'); //通过pipe读取流流入写入流 readerStream.pipe(writerStream); console.log('ok!');
十、模块系统
Node.js 提供了exports 和 require 两个对象,其中 exports 是模块公开的接口,require 用于从外部获取一个模块的接口,即所获取模块的 exports 对象。 nodejs中模块化编程最主要的一个特征就是常常可以在很多js文件看到require(),也就是引入其他的js文件,非常类似与其他语言中的import或include。同时如果想要require('A'),那么在A文件中必须要使用exports这个关键字表明要导出什么变量或函数。
//引入同一目录下的name.js var name = require('./name'); //使用name.js中的变量 console.log(name.name1); //调用name.js中的函数 name.getName(); //变量 var name1 = "Jack"; //函数 function getName() { console.log("Mary"); } //分别导出变量和函数 module.exports.name1 = name1; module.exports.getName = getName; 简化以上代码://name.jsvar name1="jack";function getName(){ console.log("Mary");}//导出变量和函数module.exports={ name1,//es6语法(name1:name1) getName}//引入变量和函数var name = require('./name'); console.log(name.name1);//jackname.getName();//Mary