Node.js 学习之路

一、创建第一个简单应用

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 – 退出 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;
//实例化一个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











    原文作者:a2774206
    原文地址: https://segmentfault.com/a/1190000009979209
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞