当前位置: 首页 > 后端技术 > Node.js

Node.js学习总结

时间:2023-04-03 14:43:59 Node.js

Node.js回调Node.js异步编程的直接体现就是回调。阻塞代码:constfs=require("fs");letdata=fs.readFileSync('input.txt');console.log(data.toString());console.log("程序执行结束");非阻塞代码:constfs=require("fs");fs.readFile('input.txt',(error,data)=>{if(error)returnconsole.log(error);console.log(data.toString());});console.log("程序执行结束");Node.js事件循环Node.js是单进程单线程应用,但是通过事件和回调支持并发,所以性能非常高。进程:CPU执行任务的模块。线程:模块中的最小单元。Node.js使用事件驱动模型。事件需要eventEmitter.on绑定一个事件,通过eventEmitter.emit触发这个事件。其次,接收事件和产生事件的代码分离如下://引入事件模块constevents=require('events');//创建一个eventEmitter对象leteventEmitter=newevents.EventEmitter();//可以同时使用.on和.addListenereventEmitter.on('dataReceived',(data)=>{console.log(`Theaccepteddatais:${data}`);});//触发dataReceived事件eventEmitter.emit('数据接收');继承EventEmitter很多时候我们不会直接使用EventEmitter,而是在对象中继承。包括fs、net、http,只要是支持事件响应的核心模块都是EventEmitter的子类。如果事件队列中有未绑定的事件,就会触发错误事件。如果未绑定错误事件,程序将抛出异??常并结束执行。emitter.emit('错误');程序会直接中断,抛出异常。Node.jsBuffer该类用于创建一个专门用于存储二进制数据的缓冲区。v6.0之后,官方文档推荐使用Buffer.from()接口创建Buffer对象。缓冲区和字符串编码缓冲区实例通常用于表示编码字符序列,例如UTF-8、UCS2、Base64或十六进制编码数据。可以使用显式字符编码将缓冲区实例与普通JavaScript字符串相互转换。constbuf=Buffer.from('hello','utf8');//输出hex编码的内容console.log(buff.toString('hex'));//输出base64编码的内容console.log(buf.toString('base64'));通过fromandallocation(n:allocation)创建一个Buffer类//创建一个长度为10的Buffer,填充0constbuf1=Buffer.alloc(10);//创建一个长度为10的Buffer,填充0用0x1填充它。constbuf2=Buffer.alloc(10,1);//创建一个长度为10的未初始化Buffer。//这种方法比调用Buffer.alloc()更快,但是返回的Buffer实例可能包含旧数据,//所以需要使用fill()或write()重写。constbuf3=Buffer.allocUnsafe(10);//创建一个包含[0x1,0x2,0x3]的缓冲区。//如果是字符串,会被0覆盖constbuf4=Buffer.from([1,2,3]);//创建一个包含UTF-8字节的Buffer[0x74,0xc3,0xa9,0x73,0x74].constbuf5=Buffer.from('tést');//创建一个包含Latin-1字节[0x74,0xe9,0x73,0x74]的缓冲区。constbuf6=Buffer.from('tést','latin1');写入缓冲区buf.write(string,[offset],[length],[encoding]);参数说明:string-写入缓冲区字符串的字符。offset-开始写入的索引值,默认为0。length-写入的字节数,默认为buffer.length。encoding-要使用的字符编码,默认为“utf8”。//分配一个256字节的缓冲区letbuf=Buffer.alloc(256);letlen=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(vari=0;i<26;i++){buf[i]=i+97;}console.日志(buf.toString('ascii'));//输出:abcdefghijklmnopqrstuvwxyzconsole.log(buf.toString('ascii',0,5));//输出:abcdeconsole.log(buf.toString('utf8',0,5));//输出:abcdeconsole.log(buf.toString(undefined,0,5));//使用'utf8'编码,并输出:abcdeBuffer转换为JSON对象buf.toJSON();缓冲区合并varbuffer3=Buffer.concat([buffer1,buffer2]);复制缓冲区buf.copy([targetBuffer],[targetStart],[sourceStart],{sourceEnd});eg:buf2.copy(buf1,2)//将buf2插入buf1指定的位置Node.jsStream(流)Stream是一个抽象接口,Node中很多对象都实现了这个接口。比如向http服务器发起请求的request对象是一个Stream,stdout(标准输出)。所有的Stream对象都继承了EventEmitter类,所以它们有以下事件:数据——当有数据可读时触发。end-当没有更多数据可读时触发。error-在接收和写入过程中发生错误时触发。finish-当所有数据都已写入底层系统时触发。从流中读取数据constfs=require("fs");letdata="";//创建可读流letreadStream=fs.createReadStream('input.txt');readStream.on('data',(chunk)=>{data+=chunk;})readStream.on('end',()=>{console.log(data);})...写流varfs=require("fs");vardata='百度官网地址:www.baidu.com';//创建一个可以写入的流,写入文件output.txtvarwriterStream=fs.createWriteStream('output.txt');//写入datausingutf8encodingwriterStream.write(data,'UTF8');//标记文件结束writerStream.end();//处理流事件-->data,end,anderrorwriterStream.on('finish',()=>{console.log("写入完成。");});管道流可以实现大文件的拷贝。constfs=require('fs');letrs=fs.createReadStream('input.txt');letws=fs.createWriteStream('output.txt');//管道读写操作//读取输入。txt,将内容写入output.txt文件rs.pipe(ws);链式流Chained是一种通过将输出流连接到另一个流来创建多个流操作链的机制。链式流通常用于管道操作。接下来我们使用管道和链来压缩和解压缩文件。varfs=require("fs");varzlib=require('zlib');//将input.txt文件压缩为input.txt.gzfs.createReadStream('input.txt').pipe(zlib.createGzip()).pipe(fs.createWriteStream('input.txt.gz'));console.log("文件压缩完成。");Node.js全局对象Node.js中的全局对象是全局的,所有的全局变量(除了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。varfs=require("fs");打开文件fs.open(path,flags,[mode],callback);路径-文件路径。flags-文件打开的行为。(rr+rs[sync]wa[append]...)mode-设置文件模式(权限),默认创建文件权限为0666(可读,可写)。callback-回调函数,有两个参数如:callback(err,fd)。获取文件信息下面是异步方式获取文件信息的语法格式:fs.stat(path,callback)//带两个参数:(err,stats)可以通过中提供的方法判断文件的相关属性统计类。如果它是一个文件,stats.isFile()返回true,否则返回false。如果它是一个目录,stats.isDirectory()返回true,否则返回false。如果它是块设备,stats.isBlockDevice()返回true,否则返回false。如果是字符设备,stats.isCharacterDevice()返回true,否则返回false。stats.isSymbolicLink()如果是符号链接则返回真,否则返回假。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,mode为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)打开文件,读取文件,关闭文件示例代码:varfs=require("fs");varbuf=newBuffer(1024);console.log("Ready打开文件!");fs.open('input.txt','r+',function(err,fd){if(err){returnconsole.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[filelist])删除目录fs.rmdir(path,callback);Node.js模块osmoduleos模块提供了一些基本的系统操作功能。varos=require("os");//CPU字节顺序console.log('endianness:'+os.endianness());//操作系统名称console.log('type:'+os.type());//操作系统名称console.log('platform:'+os.platform());//系统总内存console.log('totalmemory:'+os.totalmem()+"bytes.");//操作系统中的空闲内存量console.log('freememory:'+os.freemem()+"bytes.");pathmodulevarpath=require("path");//格式化路径console.log('normalization:'+path.normalize('/test/test1//2slashes/1slash/tab/..'));//规范化:/test/test1/2slashes/1slash//连接路径console.log('jointpath:'+path.join('/test','test1','2slashes/1slash','tab','..'));//联合路径:/test/test1/2slashes/1slash//转换为绝对路径console.log('resolve:'+path.resolve('main.js'));//resolve:/web/com/1427176256_27423/main.js//路径中文件的后缀名console.log('extname:'+path.extname('main.js'));//分机名称:.jsDNS模块dns.lookup(hostname,[options(4|6)],callback);//解析域名vardns=require('dns');dns.lookup('www.github.com',functiononLookup(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));});});