一、创建第一个简单应用
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);//端口8888
console.log('Server running at http://127.0.0.1:8888/');
2.打开打开浏览器访问 http://127.0.0.1:8888/查看状态
浏览器中响应helloword及创建成功
二、npm的使用
(说明)
-允许用户从NPM服务器下载别人编写的第三方包到本地使用。
-允许用户从NPM服务器下载并安装别人编写的命令行程序到本地使用。
-允许用户将自己编写的包或命令行程序上传到NPM服务器供别人使用。
(查看是否安装)
$ node -v
(npm旧版本升级)
$npm install npm -g
(使用 npm 命令安装模块)
$ npm install <Module Name>
比如安装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
– 退出 NodeREPL. 向上/向下 键 – 查看输入的历史命令 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;
//实例化一个eventEmitter
var 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')) // 输出: abcdefghijklmnopqrstuvwxyz console.log( buf.toString('ascii',0,5)); // 输出: abcde console.log( buf.toString('utf8',0,5));// 输出: abcde console.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.js
var 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.js
var name1="jack";
function getName(){
console.log("Mary");
}
//导出变量和函数
module.exports={
name1,//es6语法(name1:name1)
getName
}
//引入变量和函数
var name = require('./name');
console.log(name.name1);//jack
name.getName();//Mary