NodeJS 知识点
Node 是什么?
Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境,Node 不是一门语言,是让 js 运行在后端的,运行时不包括 js 全集,因为在服务端中不包含 DOM 和 BOM,Node 也提供了一些新的模块,比如 http,fs等模块。
Node 解决了什么?
- Node 的首要目标是提供一种简单的,用于创建高性能服务器的开发工具 Web 服务器的瓶颈在于并发的用户量,对比 Java 和 Php 的实现方式
- Node在处理高并发,I/O 密集场景有明显的性能优势
- 高并发,是指在同一时间并发访问服务器
- I/O 密集指的是文件操作、网络操作、数据库,相对的有 CPU 密集,CPU 密集指的是逻辑处理运算、压缩、解压、加密、解密
进程与线程 : 进程是操作系统分配资源和调度任务的基本单位,线程是建立在进程上的一次程序运行单位,一个进程上可以有多个线程。
1. 浏览器线程
- 用户界面-包括地址栏、前进/后退按钮、书签菜单等
- 浏览器引擎-在用户界面和呈现引擎之间传送指令(浏览器的主进程)
- 渲染引擎,也被称为浏览器内核(浏览器渲染进程)
- 一个插件对应一个进程(第三方插件进程)
- GPU提高网页浏览的体验( GPU 进程)
2.浏览器渲染引擎
- 渲染引擎内部是多线程的,内部包含 ui 线程和 js 线程
- js 线程 ui 线程 这两个线程互斥的,目的就是为了保证不产生冲突。
- ui 线程会把更改的放到队列中,当 js 线程空闲下来的时候,ui 线程在继续渲染
3.js 单线程
- js 是单线程,为什么呢?如果多个线程同时操作 DOM ,哪页面不会很混乱?这里所谓的单线程指的是主线程是单线程的,所以在 Node 中主线程依旧是单线程的。
4.webworker 多线程
- 它和 js 主线程不是平级的,主线程可以控制 webworker,但是 webworker不能操作 DOM,不能获取 document,window
5.其他线程
- 浏览器事件触发线程(用来控制事件循环,存放 setTimeout、浏览器事件、ajax 的回调函数)
- 定时触发器线程(setTimeout 定时器所在线程)
- 异步 HTTP 请求线程(ajax 请求线程)
单线程特点是节约了内存,并且不需要在切换执行上下文。而且单线程不需要管锁的问题。
CommonJS 规范
大致过程:
(1)node对模块进行路径、文件分析,创建模块对象o,模块对象o中保存了模块的exports、filename、require、module等属性以及文件路径、文件目录等,模块对象o的作用是存储数据;
(2)然后开始编译:将模块文件的内容封装成一个函数a,实现作用域隔离(单独函数作用域),调用某特定函数执行函数a,这样得到函数b,函数b的作用是外界通过调用该函数获取本模块的数据;
(3)当外界引入本模块时,实际上将模块对象o中保存的export、require、module等属性或方法作为参数传递给函数b,执行函数b,返回结果是模块对象的exports属性,而模块对象中的其他变量属性则没有提供给外界。
非堵塞IO
可以简单理解为异步。
- I/O:即 Input/output 指一个系统的输入和输出
- 非阻塞和阻塞的主要区别在:在接收输入到输出结果之间的过程中,能否继续接收其他的输入。
EventLoop(事件循环)
即事件循环,是指浏览器或Node的一种解决javaScript单线程运行时不会阻塞的一种机制,也就是我们经常使用异步的原理。
事件队列
node事件队列可分为6个阶段:
1.timers 阶段:这个阶段执行timer(setTimeout、setInterval)的回调
2.I/O callbacks 阶段:执行一些系统调用错误,比如网络通信的错误回调
3.idle, prepare 阶段:仅node内部使用
4.poll 阶段:获取新的I/O事件, 适当的条件下node将阻塞在这里
5.check 阶段:执行 setImmediate() 的回调
6.close callbacks 阶段:执行 socket 的 close 事件回调
重点看timers、poll、check这3个阶段就好,因为日常开发中的绝大部分异步任务都是在这3个阶段处理的。
文件系统
1. 导入文件模块
var fs = require('fs');
2. fs 模块的常用函数
(1) 读文件
① readFile():用于异步读取数据。(非阻塞方式读)
fs.readFile(fileName,function(err,buffer){ // 异步读取文件if(err) throw err; process(buffer);
})
fileName :文件名,包含路径
function(err,buffer) : 回调函数,err存放的是读文件失败的信息,buffer存放的是文件内容。
② readFileSync() : 用于同步读取文件,返回一个字符串。(阻塞方式读)
// 同步读文件,函数的返回值是字符串(文件内容)
var text = fs.readFileSync(fileName, 'utf8');
第二个参数指定字符集,若不指定,则函数返回Buffer;若指定,则返回字符串。
(2)打开文件
fs.open(path, flags[ , mode] , callback)
path:文件名(包含路径)
flags:打开文件的方式
mode:设置文件模式,但前提是已创建该文件。默认为0666,读取和写入。
callback:这是回调函数有两个参数(err,fd)
–‘r’:以只读方式打开文件,若文件不存在则报异常
–‘w’:为写打开文件,若文件则创建文件
–‘a’:向文件中追加内容,若文件则创建文件
–‘rs’:同步方式打开文件
//1.导入fs模块
const fs = require('fs');fs.open('input.txt','r+',function (err,fd) {if(err){return console.error(err)}console.log("fd:",fd);console.log('打开文件成功!');
})// fd: 3
// 打开文件成功!
(3) 获取文件信息
是一个对象,包含文件或目录(文件夹)的具体信息。通过该对象可以判断当前处理的是对象还是目录。
fs.stat(path, callback)
‘path’: 文件名,包括路径字符串。
‘callback’:回调函数得到两个参数(err, stats)
// 1. 导入fs模块
const fs = require('fs')
fs.stat('text' , function(err,stats){if(err) return console.error(err)console.log(“文件状态”,stats)// 检查console.log('isFile?---',stats.isFile()) //判断对象是否是文件console.log('isDirectory',stats.isDirectory()) // 判断对象是否是目录
})
// 文件状态: Stats {
// dev: 3959906401,
// mode: 16822,
// nlink: 1,
// uid: 0,
// gid: 0,
// rdev: 0,
// blksize: 4096,
// ino: 27584547718321690,
// size: 0,
// blocks: 0,
// atimeMs: 1645523918307.2014,
// mtimeMs: 1645523918307.2014,
// ctimeMs: 1645523918307.2014,
// birthtimeMs: 1645523918307.2014,
// atime: 2022-02-22T09:58:38.307Z,
// mtime: 2022-02-22T09:58:38.307Z,
// ctime: 2022-02-22T09:58:38.307Z,
// birthtime: 2022-02-22T09:58:38.307Z
// }
// isFile? ---- false
// isDirectory?---- true
(4)写入文件
fs.writeFile(filename,data[,options],callback)
① writeFile 异步写入文件
‘filename’ : 文件名,包括路径字符串
‘data’:字符串或缓冲区将被写入到文件中
‘options’: 一个对象,用于指定编码格式。默认编码是UTF8。
‘callback’: 回调函数获取一个参数err,用于在发生任何写入错误时返回错误。
const fs = require('fs');//1.向input.txt中写入内容
fs.writeFile('input.txt','云与海',function (err) {if(err){return console.error(err)}console.log('写入文件成功!');
})
② writeFileSync(fileName,data,‘utf8’) // 同步写
fs.writeFileSync(fileName, str, 'utf8');
(5) 读取文件(以二进制方式读)
fs.read(fd,buffer,offset,length,positon,callback)
‘fd’:是文件的描述符,由open函数返回
‘buffer’:缓冲区。存放从二进制文件读取的内容
‘offset’:偏移量。写入缓冲区的位置
‘length’:读取的字节数
‘position’:表示从文件的某个位置读。默认从当前位置开始
‘callback’:回调函数
const fs = require('fs');//读取二进制文件
var buf = new Buffer(1024);
fs.open('input.txt','r+',function (err,fd) {if(err){return console.error(err)}console.log('打开文件成功!')fs.read(fd,buf,0,buf.length,0,function (err,bytes) {if (err){return console.error(err);}if(bytes > 0){let str = buf.slice(0,bytes).toString();console.log("读取的内容是:",str);}})console.log('----End----');
})// 打开文件成功!
// ----End----
// 读取的内容是: 离离原上草,一岁一枯荣
(6) 关闭文件
close(fd,callback)
const fs = require('fs');//读取二进制文件
var buf = new Buffer(1024);
fs.open('input.txt','r+',function (err,fd) {if(err){return console.error(err)}console.log('打开文件成功!')fs.read(fd,buf,0,buf.length,0,function (err,bytes) {if (err){return console.error(err);}if(bytes > 0){let str = buf.slice(0,bytes).toString();console.log("读取的内容是:",str);}})fs.close(fd,function (err) {if (err){return console.error(err)}console.log('文件关闭成功!')})console.log('----End----');
})// 打开文件成功!
// ----End----
// 读取的内容是: 离离原上草,一岁一枯荣
// 文件关闭成功!
(7)创建目录(文件夹)
mkdir(path[, mode], callback)
‘path’:要创建的包括路径的目录名
‘mode’:目录的权限,默认是可读可写
callback’:回调函数
const fs = require('fs');fs.mkdir('./yunxi',function (err) {if (err){return console.error(err)}console.log('创建目录成功!')
})
(8)删除目录
rmdir(path, callback)
const fs = require('fs');fs.rmdir('./text',function (err) {if (err){return console.error(err)}console.log('删除成功!')
})
(9)读取目录
readdir(path, callback)
‘path’:目录名
‘callback’:回调函数,有两个参数(err,files),'files’是列表,当中放的是当前目录下的文件或文件夹名称
onst fs = require('fs');fs.readdir('./yunxi',function (err,files) {if (err){return console.error(err)}files.forEach(function (file) {console.log(file)})
})
// demo.css
// exam.ts
// zhou
(10)文件拷贝
copyFile(源文件,目标文件,回调函数)
const fs = require('fs');fs.copyFile('./input.txt','./target.txt',function (err) {if (err){return console.error(err)}console.log('文件拷贝成功!')
})
//target文件中拷贝了input文件里的内容
(11)给文件中追加内容
appendFile(filename,content,callback)
‘content’:追加的内容
const fs = require('fs');
let content = "\n野火烧不尽,\n春风吹又生";
fs.appendFile('./input.txt',content,function (err){if (err){return console.error(err)}console.log('追加内容成功!');
})
//input文件中的内容是:离离原上草,一岁一枯荣。野火烧不尽,春风吹又生。
(12)删除文件
unlink(path, callback)
‘path’:带路径的文件名
allback’:回调函数,没有参数
const fs = require('fs');
fs.unlink('./target.txt',function (err) {if (err){return console.error(err)}console.log('删除文件成功!')
})
(13)文件重命名
rename(oldPath, newPath, callback)
‘oldPath’:原文件名
‘newPath’:新文件名
‘callback’:回调函数
const fs = require('fs');
fs.rename('./input.txt','./yunxi.txt',function (err){if (err){return console.error(err)}console.log('重命名成功!')
})
//将input文件重命名为yunxi
Buffer对象
Buffer对象用于表示固定长度的字节序列。
// 创建一个长度为 10、以零填充的 Buffer。
const buf1 = Buffer.alloc(10);
// 创建一个长度为 10 的 Buffer,
// 其中全部填充了值为 `1` 的字节。
const buf2 = Buffer.alloc(10, 1);
var str="hello Jasen";
var buf = new Buffer.from(str,'utf-8');
console.log(buf);//输出:<Buffer 68 65 6c 6c 6f 20 4a 61 73 65 6e>
观察输出的结果,Buffer对象类似一个数组。
Buffer对象中的每个元素都是16进制的两位数(即0到255的数值)
对Buffer某个元素赋值如果小于0的,会逐次加256,直到得到一个0到255范围的值,如果大于255则逐次减256,直到得到0-255范围得值,如果是小数的话,则直接取整。
使用场景:
- 可用于处理大量二进制数据
- 处理图片、文件接收上传、网络协议等等
优势:
网络传输中,性能提升 :
大部分网络传输的时候会使用通过使用字符串,这难免需要转换成Buffer,以二进制方式进行数据传输。如果我们直接预先转换为Buffer 再进行传输,那么在传输过程中无需做额外的转换,也避免了损耗,使性能得到提升。
Node.js 中有四种基本的流类型:
- Writable - 可写入数据的流(例如 fs.createWriteStream())
- Readable - 可读取数据的流(例如 fs.createReadStream())。
- Duplex - 可读又可写的流(例如 net.Socket)。
- Transform - 在读写过程中可以修改或转换数据的 Duplex 流
场景:
文件分片上传下载,比如下载电影时可以边下载边看,这样一个实现过程。
字符编码
Node.js 目前支持的字符编码包括:
- ascii - 仅支持 7 位 ASCII 数据,如果设置去掉高位的话,这种编码是非常快的。
- utf8 - 多字节编码的 Unicode 字符,许多网页和其他文档格式都使用 UTF-8 。
- utf16le - 2 或 4 个字节,小字节序编码的 Unicode 字符,支持代理对(U+10000 至 U+10FFFF)。
- ucs2 - utf16le 的别名。
- base64 - Base64 编码。
- latin1 - 一种把 Buffer 编码成一字节编码的字符串的方式。
- binary - latin1 的别名。
- hex - 将每个字节编码为两个十六进制字符。
https://blog.csdn.net/qq_39055970/article/details/119756714
NodeJS 知识点相关推荐
- NodeJS知识点梳理-第一篇
文章目录 写在前面 什么是NodeJS NodeJS为什么会那么火 使用NodeJS需要会的技术 安装NodeJS 验证安装 工具使用 NodeJS全局变量初识 认识global V8引擎基本介绍 m ...
- NodeJS知识点梳理-第二篇
文章目录 Node创建服务器 [http模块] Buffer & Stream [缓存区] 读写数据流 管道事件 [pipe] 写个好玩的 本地服务渲染Html以及JSON 渲染Html 渲染 ...
- Nodejs知识点总结及个人学习心得
Nodejs是一个基于Chrome V8引擎的JavaScript运行环境 node菜鸟文档 node中文文档 node千峰 七天学会Nodejs 1.Node.js环境的安装 两个版本:LTS和Cu ...
- nodejs知识点总结
nodeJS 1.搭建服务器 2.mongodb 用 注册和登录增删改查新闻(bootstrap) 3.api server 注册和登录增删改查新闻(bootstrap) 4.bcrypt加密 注册和 ...
- nodejs知识点小整理
1. vs code 里面如何切换自定义终端? 2. 浏览器 vs node 异: node里面没有 BOM DOM node多了很多自带的api 同: 都是chrome v8 都支持js 都支持 E ...
- AMD/CMD/CommonJs到底是什么?它们有什么区别?
这篇文章总结的很好. 知道JS有模块化开发的说法,也偶尔听过requireJs,AMD,CMD等等名字,甚至使用node的时候,还用过require之类的方法,但是对这些一直没有一个明确的认识和概念. ...
- node.js学习文档_学习NodeJs从每天一个小知识点开始
NodeJs中process.cwd()与__dirname的区别: process.cwd() : 是当前执行node命令时候的文件夹地址 --工作目录,保证了文件在不同的目录下执行时,路径始终不变 ...
- nodejs模块化设计知识点总结
文章目录 前言 一.什么是模块化? 1.Node中的模块化如何实现? 2.Node中的模块分类 二.自定义模块 1.加载自定义模块 三.内置模块 1.fs.readFile读取文件 2.fs.writ ...
- 七天学会NodeJS
2019独角兽企业重金招聘Python工程师标准>>> NodeJS基础 什么是NodeJS JS是脚本语言,脚本语言都需要一个解析器才能运行.对于写在HTML页面里的JS,浏览器充 ...
最新文章
- perl+cgi学习
- javascript中 this 指向问题
- 准备树莓派下的模块开发环境
- python中文编程教学_中谷python中文视频教程(全38集)
- PYTHON得到pdf页数、遍历当前文件夹
- python 当日日期_Python程序寻找当日赢家
- 电子工程专业评副高总结_微电子科学与工程专业怎么样?
- docker和数据卷问题探究
- 易语言服务端与客户端怎么传送_配置中心是怎么推送的?动手实现一个 Long Polling 长轮询...
- shark学习(1)【原创】
- 显著性目标检测matlab代码_YOLO v3 目标检测终篇(附完整 GitHub 代码)
- 有关于阿里云的历史-阿里云这群疯子
- win10PPT不支持Flash动画
- python用于绘制数据图表的是_python图表绘制
- linux机顶盒 安卓机顶盒 优劣势分析,网络机顶盒怎么样 网络机顶盒优缺点介绍【详解】...
- 计算机u盘能直接拨出吗,电脑怎么直接拔出U盘而不丢失数据|电脑可以不用弹出设备直接拔出U盘吗...
- 统计学的Python实现-005:最大值、最小值、极差
- R语言编程环境的安装和运行
- 解决Redis持久化数据丢失
- ChatGPT 常见错误原因及解决方案:报错、回答不完整、网络错误等
热门文章
- 初中信息技术计算机的发展,中小学信息技术教材的现状与发展趋势
- 用Python求解数学规划问题
- 假设有两种微生物 X 和 YX出生后每隔3分钟分裂一次(数目加倍),Y出生后每隔2分钟分裂一次(数目加倍)。
- 第1章 初识计算机病毒 1.1 计算机病毒基础知识
- shell中 的 export命令
- 算法学习(八)——排序算法汇总
- 【LeetCode】1652. 拆炸弹(C++)
- Android-进阶教程-权限-安装时权限-签名权限-signature|privileged
- 北京燕化附中2021年高考成绩查询,2021年北京最好的高中排名,北京重点高中排名榜公布...
- ITIL学习(六)服务战略之战略制定