资讯专栏INFORMATION COLUMN

Node.js学习总结

kamushin233 / 1341人阅读

摘要:表示当前正在执行的脚本的文件名。默认编码为模式为,为回调函数,回调函数只包含错误信息参数,在写入失败时返回。参数使用说明如下通过方法返回的文件描述符。

Node.js回调

Node.js异步编程的直接体现就是回调。

阻塞代码:
const fs = require("fs");
let data = fs.readFileSync("input.txt");

console.log(data.toString());
console.log("程序执行结束");
非阻塞代码:
const fs = require("fs");
fs.readFile("input.txt",(error,data)=>{
    if(error) return console.log(error);
   console.log(data.toString()); 
});
console.log("程序执行结束");
Node.js事件循环

Node.js是单进程单线程应用程序,但是通过事件和回调支持并发,所以性能非常高。
进程:CPU执行任务的模块。线程:模块中的最小单元。

Node.js使用事件驱动模型。
事件就是需要 eventEmitter.on 去绑定一个事件 通过 eventEmitter.emit 去触发这个事件其次说的是 事件的 接收 和 发生 是分开的

代码如下:

// 引入events 模块
const events = require("events");
// 创建 eventEmitter 对象
let eventEmitter = new events.EventEmitter();

// 这里既可以使用.on  也可以使用 .addListener
eventEmitter.on("dataReceived",(data) => {
    console.log(`接受的数据为:${data}`);
});

// 触发 dataReceived 事件
eventEmitter.emit("dataReceived");
继承 EventEmitter

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

若事件队列中出现一个未绑定事件则触发error事件,若未绑定 error事件则程序抛出异常结束执行 emitter.emit("error"); 程序会直接中断,并抛出异常。

Node.js Buffer缓冲区

该类用来创建一个专门存放二进制数据的缓存区。

在v6.0以后,官方文档里面建议使用 Buffer.from() 接口去创建Buffer对象。
Buffer与字符串编码

Buffer 实例一般用于表示编码字符的序列,比如 UTF-8 、 UCS2 、 Base64 、或十六进制编码的数据。 通过使用显式的字符编码,就可以在 Buffer 实例与普通的 JavaScript 字符串之间进行相互转换。

const buf = Buffer.from("hello","utf8");

// 输出 hex 编码后的内容
console.log(buff.toString("hex"));

// 输出 base64 编码后的内容
console.log(buf.toString("base64"));
创建 Buffer 类

通过 from 和 allocation(n:分配)

// 创建一个长度为 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。
// 如果是字符串会被 0 覆盖
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");
写入缓冲区

buf.write(string,[offset],[length],[encoding]);
参数描述:

string - 写入缓冲区的字符串。

offset -开始写入的索引值,默认为0。

length -写入的字节数,默认为buffer.length。

encoding -使用的字符编码,默认为‘utf8’。

// 分配一个256字节的缓冲区
let buf = Buffer.alloc(256);
let len = buf.write("www.baidu.com");

console.log(`写入的字节数数为:${len}`);
缓冲区读取数据

buf.toString([encoding],[start],[end]);
参数描述:

encoding - 使用的编码。默认为 "utf8" 。

start - 指定开始读取的索引位置,默认为 0。

end - 结束位置,默认为缓冲区的末尾。

// 创建缓冲区并写入26个小写英文字母的ASCII码
buf = Buffer.alloc(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 对象

buf.toJSON();

缓冲区合并

var buffer3 = Buffer.concat([buffer1,buffer2]);

拷贝缓冲区

buf.copy([targetBufffer],[targetStart],[sourceStart],{sourceEnd});
eg: buf2.copy(buf1,2) // 将buf2插入到buf1指定的位置上

Node.js Stream(流)

Stream 是一个抽象接口,Node 中有很多对象实现了这个接口。例如,对http 服务器发起请求的request 对象就是一个 Stream,还有stdout(标准输出)。
所有的Stream对象继承了 EventEmitter 类,所以拥有以下事件:

data - 当有数据可读时触发。

end - 没有更多的数据可读时触发。

error - 在接收和写入过程中发生错误时触发。

finish - 所有数据已被写入到底层系统时触发。

从流中读取数据
const fs = require("fs");
let data = "";

// 创建可读流
let readStream = fs.createReadStream("input.txt");
readStream.on("data",(chunk)=>{
    data += chunk;
})
readStream.on("end",()=>{
    console.log(data);
})
...
写入流
var fs = require("fs");
var data = "百度官网地址:www.baidu.com";

// 创建一个可以写入的流,写入到文件 output.txt 中
var writerStream = fs.createWriteStream("output.txt");

// 使用 utf8 编码写入数据
writerStream.write(data,"UTF8");

// 标记文件末尾
writerStream.end();

// 处理流事件 --> data, end, and error
writerStream.on("finish", ()=> {
    console.log("写入完成。");
});
管道流

可以实现大文件的复制。

const fs = require("fs");
let rs = fs.createReadStream("input.txt");
let ws = fs.createWriteStream("output.txt");

// 管道读写操作
// 读取input.txt,将内容写入到output.txt文件中
rs.pipe(ws);
链式流

链式是通过连接输出流到另外一个流并创建多个流操作链的机制。链式流一般用于管道操作。
接下来我们就是用管道和链式来压缩和解压文件。

var fs = require("fs");
var zlib = require("zlib");

// 压缩 input.txt 文件为 input.txt.gz
fs.createReadStream("input.txt")
  .pipe(zlib.createGzip())
  .pipe(fs.createWriteStream("input.txt.gz"));
 
console.log("文件压缩完成。");
Node.js全局对象

Node.js 中的全局对象是 global,所有全局变量(除了 global 本身以外)都是 global 对象的属性。
__filename :表示当前正在执行的脚本的文件名。(输出文件所在的绝对路径)
__ __dirnname __:表示当前执行脚本呢所在的目录。
__ process __:它用于描述当前Node.js 进程状态的对象。

Node.js常用工具

util是一个node。js核心模块,提供常用的函数的集合。

util.inherits(constructor,superConstructor) 是一个实现对象间原型继承的函数。(构造函数中的属性和函数不会被继承)。

util.inspect(object,[showHidden],[depth],[colors]) 是一个将任意对象转换 为字符串的方法,通常用于调试和错误输出。

util.isArray(object) 判断是否为一个数组。

util.isRegExp(object) 判断是否为一个正则表达式。

util.isDate(object) 判断是否为一个日期。

Node.js 文件系统

Node.js 提供一组标准的文件操作API。

var fs = require("fs");
打开文件
fs.open(path,flags,[mode],callback);

path -文件路径。

flags -文件打开的行为。(r r+ rs[同步] w a[追加]...)

mode - 设置文件模式(权限),文件创建默认权限为 0666(可读,可写)。

callback - 回调函数,带有两个参数如:callback(err, fd)。

获取文件信息

以下为通过异步模式获取文件信息的语法格式:

fs.stat(path,callback) // 带两个参数:(err,stats)

可以通过stats类中的提供方法判断文件的相关属性。

stats.isFile() 如果是文件返回 true,否则返回 false。

stats.isDirectory() 如果是目录返回 true,否则返回 false。

stats.isBlockDevice() 如果是块设备返回 true,否则返回 false。

stats.isCharacterDevice() 如果是字符设备返回 true,否则返回 false。

stats.isSymbolicLink() 如果是软链接返回 true,否则返回 false。

stats.isFIFO() 如果是FIFO,返回true,否则返回 false。FIFO是UNIX中的一种特殊类型的命令管道。

stats.isSocket() 如果是 Socket 返回 true,否则返回 false。

写入文件

以下为异步模式下写入文件的语法格式:

fs.writeFile(file, data,[options], callback)

如果文件存在,该方法写入的内容会覆盖旧的文件内容。

参数使用说明如下:

file - 文件名或文件描述符。

data - 要写入文件的数据,可以是 String(字符串) 或 Buffer(流) 对象。

options - 该参数是一个对象,包含 {encoding, mode, flag}。默认编码为 utf8, 模式为 0666 , flag 为 "w"

callback - 回调函数,回调函数只包含错误信息参数(err),在写入失败时返回。

读取文件

以下为异步模式下读取文件的语法格式:

fs.read(fd, buffer, offset, length, position, callback)

该方法使用了文件描述符来读取文件。

参数使用说明如下:

fd - 通过 fs.open() 方法返回的文件描述符。

buffer - 数据写入的缓冲区。

offset - 缓冲区写入的写入偏移量。

length - 要从文件中读取的字节数。

position - 文件读取的起始位置,如果 position 的值为 null,则会从当前文件指针的位置读取。

callback - 回调函数,有三个参数err, bytesRead, buffer,err 为错误信息, + bytesRead 表示读取的字节数,buffer 为缓冲区对象。

关闭文件
fs.close(fd,callback)

打开文件,读取文件,关闭文件示例代码:

var fs = require("fs");
var buf = new Buffer(1024);

console.log("准备打开文件!");
fs.open("input.txt", "r+", function(err, fd) {
   if (err) {
       return console.error(err);
   }
   console.log("文件打开成功!");
   console.log("准备读取文件!");
   fs.read(fd, buf, 0, buf.length, 0, function(err, bytes){
      if (err){
         console.log(err);
      }

      // 仅输出读取的字节
      if(bytes > 0){
         console.log(buf.slice(0, bytes).toString());
      }

      // 关闭文件
      fs.close(fd, function(err){
         if (err){
            console.log(err);
         } 
         console.log("文件关闭成功");
      });
   });
});
删除文件
fs.unlink(path,callback);
创建目录
fs.mkdir(path,[mode],callback);
读取目录
fs.readdir(path,callback);  // callback(err,files[文件列表])         
删除目录
fs.rmdir(path,callback);    

Node.js 模块 os模块

os模块提供了一些基本的系统操作函数。

var os = require("os");

// CPU 的字节序
console.log("endianness : " + os.endianness());

// 操作系统名
console.log("type : " + os.type());

// 操作系统名
console.log("platform : " + os.platform());

// 系统内存总量
console.log("total memory : " + os.totalmem() + " bytes.");

// 操作系统空闲内存量
console.log("free memory : " + os.freemem() + " bytes.");
path模块
var path = require("path");

// 格式化路径
console.log("normalization : " + path.normalize("/test/test1//2slashes/1slash/tab/..")); // normalization : /test/test1/2slashes/1slash

// 连接路径
console.log("joint path : " + path.join("/test", "test1", "2slashes/1slash", "tab", "..")); // joint path : /test/test1/2slashes/1slash

// 转换为绝对路径
console.log("resolve : " + path.resolve("main.js")); // resolve : /web/com/1427176256_27423/main.js

// 路径中文件的后缀名
console.log("ext name : " + path.extname("main.js")); // ext name : .js
DNS模块

dns.lookup(hostname,[options(4|6)],callback); // 解析域名

var dns = require("dns");

dns.lookup("www.github.com", function onLookup(err, address, family) {
   console.log("ip 地址:", address);
   dns.reverse(address, function (err, hostnames) {
   if (err) {
      console.log(err.stack);
   }

   console.log("反向解析 " + address + ": " + JSON.stringify(hostnames));
   });  
});

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/107340.html

相关文章

  • 前端最实用书签(持续更新)

    摘要:前言一直混迹社区突然发现自己收藏了不少好文但是管理起来有点混乱所以将前端主流技术做了一个书签整理不求最多最全但求最实用。 前言 一直混迹社区,突然发现自己收藏了不少好文但是管理起来有点混乱; 所以将前端主流技术做了一个书签整理,不求最多最全,但求最实用。 书签源码 书签导入浏览器效果截图showImg(https://segmentfault.com/img/bVbg41b?w=107...

    sshe 评论0 收藏0
  • Node.js技术总结

    摘要:使用了一个事件驱动非阻塞式的模型,使其轻量又高效。依赖就近,延迟执行。使用错误处理中间件默认情况下,给出的响应是状态码,包含文本以及错误自身详细信息的响应主体。 Node.js是什么 官网定义: Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。 Node.js 使用了一个事件驱动、非阻塞式I/O 的模型,使其轻量又高效。 非阻塞 I/O 模型(...

    SKYZACK 评论0 收藏0
  • babel使用方法总结

    摘要:在项目根目录下创建一个文件,注意这是个配置文件,以点号开头,没有后缀。提供了一种可以在浏览器中使用的方法,只需两步就能一劳永逸。 1.在命令行中使用 Babel Babel 官方推荐将 Babel 安装在本地,因为 Babel 的不同版本以及不同转码规则会起到不同的效果,全局安装会带来不必要的麻烦。在命令提示符中转到自己的项目目录下: npm install --save-dev ba...

    沈俭 评论0 收藏0
  • 教你如何打好根基快速入手react,vue,node

    摘要:谨记,请勿犯这样的错误。由于在之前的教程中,积累了坚实的基础。其实,这是有缘由的其复杂度在早期的学习过程中,将会带来灾难性的影响。该如何应对对于来说,虽然有大量的学习计划需要采取,且有大量的东西需要学习。 前言倘若你正在建造一间房子,那么为了能快点完成,你是否会跳过建造过程中的部分步骤?如在具体建设前先铺设好部分石头?或直接在一块裸露的土地上先建立起墙面? 又假如你是在堆砌一个结婚蛋糕...

    ddongjian0000 评论0 收藏0

发表评论

0条评论

kamushin233

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<