.断言 assert(assert 模块提供了一组简单的断言测试,可用于测试不变量。
存在严格模式(strict)和遗留模式(legacy),但建议仅使用严格模式)assert模块提供了一系列的断言测试,其实这个模块主要倾向于内部使用,但是也能被用于项目中, 可以通过require(‘assert’)的方式引入equal、notEqual、deepEqual、notDeepEqual:使用'=='比较符进行比较。即:不含strict的方法,使用的都是'=='比较符。
strictEqual、notStrictEqual、strictDeepEqual、notStrictDeepEqual:使用'==='比较符进行比较。
即:含strict的方法,使用的都是'==='比较符。
const assert = require('assert');
assert(true); // OK
assert(1); // OK
assert(false);
// throws "AssertionError: false == true"
assert(0);
// throws "AssertionError: 0 == true"
assert(false, 'it\'s false');
// throws "AssertionError: it's false"
const obj1 = {
a : {
b : 1
}
};
const obj2 = {
a : {
b : 2
}
};
const obj3 = {
a : {
b : 1
}
}
const obj4 = Object.create(obj1);
assert.deepEqual(obj1, obj1);
// OK, object is equal to itself
assert.deepEqual(obj1, obj2);
// AssertionError: { a: { b: 1 } } deepEqual { a: { b: 2 } }
// values of b are different
assert.deepEqual(obj1, obj3);
// OK, objects are equal
assert.deepEqual(obj1, obj4);
// AssertionError: { a: { b: 1 } } deepEqual {}
// Prototypes are ignored
async_hooks(异步钩子)
async_hooks 模块,是因为在异步调用中我们很难正确的追踪异步调用的处理逻辑及关系。而 async_hooks 模块友好的解决了上述问题,主要提供以下功能和特性:每一个函数都会提供一个上下文,我们称之为 async scope;
每一个 async scope 中都有一个 asyncId, 是当前 async scope 的标志,同一个的 async scope 中 asyncId 必然相同,最外层的 asyncId 是 1,每个异步资源在创建时 asyncId 全量递增的;
每一个 async scope 中都有一个 triggerAsyncId 表示当前函数是由那个 async scope 触发生成的;
通过 asyncId 和 triggerAsyncId 我们可以很方便的追踪整个异步的调用关系及链路;
我们可以通过 async_hooks.createHook 函数来注册关于每个异步资源在生命周期中发生的 init/before/after/destory/promiseResolve 等相关事件的监听函数;
同一个 async scope 可能会被调用及执行多次,不管执行多少次,其 asyncId 必然相同,通过监听函数,我们很方便追踪其执行的次数及时间及上线文关系;
const async_hooks = require('async_hooks');
const fs = require('fs');
console.log('global.asyncId:', async_hooks.executionAsyncId()); // global.asyncId: 1
console.log('global.triggerAsyncId:', async_hooks.triggerAsyncId()); // global.triggerAsyncId: 0
fs.open('./app.js', 'r', (err, fd) => {
console.log('fs.open.asyncId:', async_hooks.executionAsyncId()); // fs.open.asyncId: 7
console.log('fs.open.triggerAsyncId:', async_hooks.triggerAsyncId()); // fs.open.triggerAsyncId: 1
});
async_hooks.createHook(callbacks)const async_hooks = require('async_hooks');
const asyncHook = async_hooks.createHook({
init(asyncId, type, triggerAsyncId, resource) { },
destroy(asyncId) { }
});
asyncHook.enable(); //通过 enable 函数开启钩子功能
init(asyncId, type, triggerAsyncId, resource)
init 回调函数一般在异步资源初始化的时候被触发,其参数解释如下:
asyncId: 每一个异步资源都会生成一个唯一性标志
type: 异步资源的类型,一般都是资源的构造函数的名字,想知道都有哪些可以参考 async_hooks官方文档
triggerAsyncId: 表示触发当前异步资源被创建的对应的 async scope 的 asyncId
resource: 代表被初始化的异步资源对象
before(asyncId)
after(asyncId)
destroy(asyncId)
promiseResolve(asyncId)
Buffer
Buffer 作为一个全局变量,不需要使用require(‘buffer’).Buffer来引入;Buffer的作用就是用来处理二进制数据流,直接对内存进行操作;Buffer的大小一旦被确定就不能被修改
Buffer底层是arrayBuffer,(buf.buffer === arrayBuffer) is true,arrayBuffer又称类型化数组,其成员是0/1二进制数据,一旦初始化则固定大小,不再扩充或缩小;arrayBuffer将数据放在栈中,数组则放在堆中,arrayBuffer取数据更快
// 创建一个长度为 10、且用 0 填充的 Buffer。
const buf1 = Buffer.alloc(10);
// 创建一个长度为 10、且用 0x1 填充的 Buffer。
const buf2 = Buffer.alloc(10,1);
// 创建一个长度为 10、且未初始化的 Buffer。
// 这个方法比调用 Buffer.alloc() 更快,
// 但返回的 Buffer 实例可能包含旧数据,
// 因此需要使用 fill() 或 write() 重写。
const buf3 = Buffer.allocUnsafe(10);
// 创建一个包含 [0x1, 0x2, 0x3] 的 Buffer。
const buf4 = Buffer.from([1, 2, 3]);
// 创建一个包含 UTF-8 字节 [0x74, 0xc3, 0xa9, 0x73, 0x74] 的 Buffer。
const buf5 = Buffer.from('tést');
// 创建一个包含 Latin-1 字节 [0x74, 0xe9, 0x73, 0x74] 的 Buffer。
const buf6 = Buffer.from('tést', 'latin1');
//.............写入缓冲区
//写如Node缓冲区的语法如下:
//buf.write(string [,offset[,length]][,encoding]);
//string -写入缓冲区的字符串
//offset -写入的字节数,默认为buffer.length
//encoding -使用的编码,默认为utf8
// --该函数返回值为实际写入大大小
buf =Buffer.alloc(256);
len=buf.write('www.runoob.com');
console.log("写入字节数:"+len);
//..............从缓冲区读取数据
// buf.toString([encoding[,start[,end]]]);
//encoding - 使用的编码,默认为utf8
//start - 指定开始读取索引的位置
//end - 结束的位置,默认为缓冲区的末尾
//-----返回值———— 解码缓冲区数据并使用指定的编码返回字符串
buf =Buffer.alloc(26);
for(var i=0;i<26;i++){
buf[i]=i+97;
}
console.log(buf.toString('ascii'));
console.log(buf.toString('ascii',0,5));
console.log(buf.toString('utf8',0,5));
console.log(buf.toString(undefined,0,5));
//缓冲区合并
//Buffer.concat(list[,totalLength]);
//list - 用于合并Buffer对象的数组
//totalLength - 指定合并后Buffer对象的总长度
//...返回值,多个成员合并后的新对象
var buffer1=Buffer.from('菜鸟教程');
var buffer2=Buffer.from('www.runoob.com');
var buffer3=Buffer.concat([buffer1,buffer2]);
console.log('buffer3内容:'+buffer3.toString());
//.....缓冲区裁剪
//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());
//....缓冲区长度
//buf.length
//方法参考
//Node.js Buffer 常用方法:
......
//将Buffer转化为JSON对象
//buf.toJSON();
//当字符串化一个Buffer实例时,JSON.stringify()会隐式的调用toJSON()方法
const buf=Buffer.from([0x1,0x2,0x3,0x4]);
//Buffer.from(array) 返回一个 Buffer,包含传入的字节数组的拷贝
const json=JSON.stringify(buf);
console.log(json);
cosnt copy=JSON.parse(json,(key,value)=>{
return value && value.type === 'Buffer' ? Buffer.from(value.data) : value;
});
console.log(copy);