Node.js:EventEmitter、Buffer

发布于:2025-07-21 ⋅ 阅读:(12) ⋅ 点赞:(0)

EventEmitter

  • Node.js所有的异步IO操作在完成时都会发送一个事件到事件队列
  • Node.js里面的许多对象都会分发事件:
  • 一个net.Server对象会在每次有新连接时候触发一个新的事件
  • 一个fs.readStream对象会在文件被打开的时候触发一个事件
    所有的这些产生事件的对象都是events.EventEmitter的实例

EventEmitter 类

  • events模块只提供了一个对象,events.EventEmitter。
  • EventEmitter的核心就是事件触发于事件监听器功能的封装
    可以通过require来导入该模块
var events = require('events');
var eventEmitter = new events.EventEmitter();
  • 如果EventEmitter对象在实例化时候出现了错误,那么会触发error事件
  • 当添加了新的监听器,newListener事件会触发,当监听器被移除,那么removeListener事件会被触发

实例如下:

var events = require("events");
var emittr = new events.EventEmitter();
emittr.on('event_on',function(){
    //绑定一个事件,当事件被触发了,就调用下面代码。
    console.log("Haha");
})
setTimeout(function(){
    emittr.emit("event_on");
    //两秒后,触发这个事件!s
},2000);

EventEmitter支持若干个事件监听器,每当执行对应的事件的时候,事件监听器会被依次调用,同时我们甚至可以向监听器中传递参数。

var events = require("events");
var emittr = new events.EventEmitter();
emittr.on('event_on',function(arg1, arg2){
    console.log("第一个监听器被触发!");
    console.log("参数1:"+arg1+", 参数2:"+arg2);
})
emittr.on('event_on', function(arg1,arg2){
    console.log("第二个监听器被触发!");
    console.log("参数1:"+arg1+", 参数2:"+arg2);
})
setTimeout(function(){
    emittr.emit("event_on", "参数1", "参数2");
    //两秒后,触发这个事件!s
},2000);

第一个监听器被触发!
参数1:参数1, 参数2:参数2
第二个监听器被触发!
参数1:参数1, 参数2:参数2

EventEmitter提供了多个属性,如on emit等,on函数用于绑定事件函数,emit用于触发一个事件

具体的方法如下:
1.addListener(event, listener)
为指定事件添加一个监听器到监听器数组的尾部

2.on(event, listener)
为指定事件注册一个监听器,接收一个字符串event和一个回调函数

3.once(event, listener)
也是注册监听器但是只是注册一次,监听器最多只会触发一次,触发之后立刻会被解除

4.removeListener(event, listener)
移除某个监听器,该监听器必须是已经注册过的,接收两个参数,一个是事件,一个是监听器的回调函数名称

5.removeAllListeners([event])
移除所有事件的所有监听器,如果没有指定事件,那么所有的监听器会被移除

6.setMaxListener(n)
改变最大的监听器默认数量警告

7.listeners(event)
返回指定事件的监听器数组

8.emit(event,[args])
按照监听器的顺序执行每个监听器,如果有注册监听返回true,否则false

9.listenerCount(emitter, event)
返回指定事件的监听器数量

10.newListener
该事件在添加新监听器时被触发。

11.removeListener
从监听器数组中删除一个监听器,需要注意的是,此操作将会改变处于被删监听器之后的那些监听器的索引。


error事件

EventEmitter定义了一个特殊的事件error,它包含了错误的语义,我们在遇到了异常的时候通常会触发error事件。当error被触发时候,EventEmitter规定如果没有响应的监听器,Node.js会把它当作异常,退出程序并输出错误信息。我们一般要为会触发error事件的对象设置监听器,避免遇到错误之后整个程序崩溃

var events = require("events");
var emitter = new events.EventEmitter( );
emitter.emit('error');

node:events:518
throw err; // Unhandled ‘error’ event
^
Error [ERR_UNHANDLED_ERROR]: Unhandled error. (undefined)
at new NodeError (node:internal/errors:372:5)
at EventEmitter.emit (node:events:516:17)
at Timeout._onTimeout (F:\微软云盘\OneDrive\桌面\de.js:4:12)
at listOnTimeout (node:internal/timers:559:17)
at processTimers (node:internal/timers:502:7) {
code: ‘ERR_UNHANDLED_ERROR’,
context: undefined
}


继承EventEmitter

大多数情况下我们不会直接使用EventEmitter,而是在对象中继承它,包括fs,net,http在内的,只要是支持事件响应的核心模块都是EventEmitter的子类

Buffer缓冲区

Javascript语言只有字符串类型数据,没有二进制类型数据
Node.js中定义了一个Buffer类专门用于处理二进制数据的缓存区
Buffer是随着Node内核一起发布的核心库
Buffer可以让Node来处理二进制数据,当需要在Node.js中处理IO操作中的移动数据的时候,就可能使用到Buffer库
原始数据存在Buffer类的实力中国,一个Buffer类似于一个整数数组,但它对应于V8堆内存之外的一块原始数据

在v6.0之前创建Buffer对象直接使用new Buffer()构造函数来创建对象实例,但是Buffer对内存的权限操作相比很大可以直接捕获一些敏感信息,所以在v6.0以后,官方文档里面建议使用Buffer.from()接口去创建Buffer对象。


Buffer和字符编码

Buffer实例一般用于表示编码字符的序列,比如Utf-8,UCS2,base64或者是Hex编码的数据,通过显式地指定编码,即可在Buffer实例中和普通的Javascript字符串之间进行相互转换

const buf = Buffer.from('runoob', 'ascii');

console.log(buf.toString('hex'));
console.log(buf.toString('base64'));

目前支持的字符集有:
Ascii、utf8、utf16le、ucs2、base64、latin1、binary、hex


创建Buffer类

Buffer提供了以下的API来创建Buffer类

  • Buffer.alloc(size,[fill, encoding]),返回一个指定大小的Buffer,如果没有设置fill,则默认填满0
  • Buffer.allocUnsafe()返回一个Buffer实例,但是不初始化
  • Buffer.from(array)返回一个被array的值初始化的新的Buffer实例,传入的array只能是数字,不然自动被0覆盖
  • Buffer.from(buffer) 用另一个buffer来初始化这个buffer
  • Buffer.from(string,[encoding]) 返回一个被string的值初始化的新的Buffer实例

写入缓冲区

语法

写入缓冲区的语法如下:

buf.write(string [, offset[, length]][, encoding])
参数
  • string 要写入的字符串
  • offset缓冲区开始写入的索引值,默认为0
  • length写入的字节数,默认为buffer.length
  • encoding 使用的编码,默认为’utf8’
返回值

返回实际写入的大小,如果不足的话就只写入部分的值

实例
buf = Buffer.alloc(256);
len = buf.write("www.runoob.com");
console.log("写入字节数: "+len);

从缓冲区读取数据

语法
buf.toString([encoding[, start [,end]]])
参数
  • encoding 使用的编码,默认为utf-8
  • start 指定从开始读取的索引位置,默认为0
  • end 结束位置,默认为缓冲区的末尾
返回值

由于保存的是二进制的数据,那么解码缓冲区会根据指定的编码来返回字符串

实例
var buf = Buffer.alloc(26);
//申请26个字节的空间来存储东西
for(i=0;i<26;i++){
    buf[i] = i + 97;
}
console.log( buf.toString('ascii'));       // 输出: abcdefghijklmnopqrstuvwxyz
console.log( buf.toString('ascii',0,5));   //使用 'ascii' 编码, 并输出: abcde
console.log( buf.toString('utf8',0,5));    // 使用 'utf8' 编码, 并输出: abcde
console.log( buf.toString(undefined,0,5)); // 使用默认的 'utf8' 编码, 并输出: abcde

Buffer和JSON对象的转换

语法

将Node Buffer转换为JSON对象的函数语法格式如下:

buf.toJSON()

当字符串化一个Buffer实例时,JSON.stringify()会隐式调用toJSON()

返回值

返回JSON对象

实例
const buf = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5]);
const json = JSON.stringify(buf);
//输出内容为{"type":"Buffer","data":[1,2,3,4,5]}
console.log(json);
const copy = JSON.parse(json, (key, value)=>{
    return value && value.type === 'Buffer'? Buffer.from(value.data) : value;
});
//输出<Buffer 01 02 03 04 05>
console.log(copy);

缓冲区合并

语法

Node缓冲区合并的语法如下所示:

Buffer.concat(list[, totalLength])
参数

参数描述如下:

  • list 用于合并的Buffer对象数组列表
  • totalLength 指定合并后Buffer对象的总长度
返回值

返回一个多个成员合并的新的Buffer对象

实例
var buffer1 = Buffer.from(('菜鸟教程'));
var buffer2 = Buffer.from(('www.runoob.com'));
var buffer3 = Buffer.concat([buffer1,buffer2]);
console.log("buffer3 内容: " + buffer3.toString());

缓冲区比较

语句

Node Buffer 比较的函数语法如下所示:

buf.compare(otherBuffer);
参数
  • otherBuffer 与buf对象比较的另外一个Buffer对象
返回值

返回一个数字,表示buf在otherBuffer之前、之后或者相同

实例
var buffer1 = Buffer.from('ABC');
var buffer2 = Buffer.from('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 + "之后");
}
//输出结果为: ABC在ABCD之前

拷贝缓冲区

语法

Node缓冲区拷贝语法如下

buf.copy(targetBuffer[, targetStart[, sourceStart[, sourceEnd]]])
参数

参数描述如下:

  • targetBuffer 要拷贝的Buffer对象
  • targetStart 数字,可选,默认0
  • sourceStart 数字,可选,默认0
  • sourceEnd 数字,可选,默认:buffer.length
返回值

没有返回值

实例
var buf1 = Buffer.from('abcdefghijkl');
var buf2 = Buffer.from('RUNOOB');
//将 buf2 插入到 buf1 指定位置上
buf2.copy(buf1, 2);
console.log(buf1.toString());

缓冲区

Node缓冲区裁剪语法如下

buf.slice([start[, end]])
参数

参数描述如下:

  • start 数字,可选,默认 0
  • end 数字,可选,默认buffer.length
实例
var buffer1 = Buffer.from('runoob');
// 剪切缓冲区
var buffer2 = buffer1.slice(0,2);
console.log("buffer2 content: " + buffer2.toString());
//输出:  buffer2 content: ru

缓冲区长度

语法

Node缓冲区长度的计算语法如下

buf.length;
返回值

返回Buffer对象所占据的内存长度

实例
var buffer = Buffer.from('www.runoob.com');
//  缓冲区长度
console.log("buffer length: " + buffer.length);
// buffer length: 14

其他方法:https://www.runoob.com/nodejs/nodejs-buffer.html


网站公告

今日签到

点亮在社区的每一天
去签到