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 知识点相关推荐

  1. NodeJS知识点梳理-第一篇

    文章目录 写在前面 什么是NodeJS NodeJS为什么会那么火 使用NodeJS需要会的技术 安装NodeJS 验证安装 工具使用 NodeJS全局变量初识 认识global V8引擎基本介绍 m ...

  2. NodeJS知识点梳理-第二篇

    文章目录 Node创建服务器 [http模块] Buffer & Stream [缓存区] 读写数据流 管道事件 [pipe] 写个好玩的 本地服务渲染Html以及JSON 渲染Html 渲染 ...

  3. Nodejs知识点总结及个人学习心得

    Nodejs是一个基于Chrome V8引擎的JavaScript运行环境 node菜鸟文档 node中文文档 node千峰 七天学会Nodejs 1.Node.js环境的安装 两个版本:LTS和Cu ...

  4. nodejs知识点总结

    nodeJS 1.搭建服务器 2.mongodb 用 注册和登录增删改查新闻(bootstrap) 3.api server 注册和登录增删改查新闻(bootstrap) 4.bcrypt加密 注册和 ...

  5. nodejs知识点小整理

    1. vs code 里面如何切换自定义终端? 2. 浏览器 vs node 异: node里面没有 BOM DOM node多了很多自带的api 同: 都是chrome v8 都支持js 都支持 E ...

  6. AMD/CMD/CommonJs到底是什么?它们有什么区别?

    这篇文章总结的很好. 知道JS有模块化开发的说法,也偶尔听过requireJs,AMD,CMD等等名字,甚至使用node的时候,还用过require之类的方法,但是对这些一直没有一个明确的认识和概念. ...

  7. node.js学习文档_学习NodeJs从每天一个小知识点开始

    NodeJs中process.cwd()与__dirname的区别: process.cwd() : 是当前执行node命令时候的文件夹地址 --工作目录,保证了文件在不同的目录下执行时,路径始终不变 ...

  8. nodejs模块化设计知识点总结

    文章目录 前言 一.什么是模块化? 1.Node中的模块化如何实现? 2.Node中的模块分类 二.自定义模块 1.加载自定义模块 三.内置模块 1.fs.readFile读取文件 2.fs.writ ...

  9. 七天学会NodeJS

    2019独角兽企业重金招聘Python工程师标准>>> NodeJS基础 什么是NodeJS JS是脚本语言,脚本语言都需要一个解析器才能运行.对于写在HTML页面里的JS,浏览器充 ...

最新文章

  1. perl+cgi学习
  2. javascript中 this 指向问题
  3. 准备树莓派下的模块开发环境
  4. python中文编程教学_中谷python中文视频教程(全38集)
  5. PYTHON得到pdf页数、遍历当前文件夹
  6. python 当日日期_Python程序寻找当日赢家
  7. 电子工程专业评副高总结_微电子科学与工程专业怎么样?
  8. docker和数据卷问题探究
  9. 易语言服务端与客户端怎么传送_配置中心是怎么推送的?动手实现一个 Long Polling 长轮询...
  10. shark学习(1)【原创】
  11. 显著性目标检测matlab代码_YOLO v3 目标检测终篇(附完整 GitHub 代码)
  12. 有关于阿里云的历史-阿里云这群疯子
  13. win10PPT不支持Flash动画
  14. python用于绘制数据图表的是_python图表绘制
  15. linux机顶盒 安卓机顶盒 优劣势分析,网络机顶盒怎么样 网络机顶盒优缺点介绍【详解】...
  16. 计算机u盘能直接拨出吗,电脑怎么直接拔出U盘而不丢失数据|电脑可以不用弹出设备直接拔出U盘吗...
  17. 统计学的Python实现-005:最大值、最小值、极差
  18. R语言编程环境的安装和运行
  19. 解决Redis持久化数据丢失
  20. ChatGPT 常见错误原因及解决方案:报错、回答不完整、网络错误等

热门文章

  1. 初中信息技术计算机的发展,中小学信息技术教材的现状与发展趋势
  2. 用Python求解数学规划问题
  3. 假设有两种微生物 X 和 YX出生后每隔3分钟分裂一次(数目加倍),Y出生后每隔2分钟分裂一次(数目加倍)。
  4. 第1章 初识计算机病毒 1.1 计算机病毒基础知识
  5. shell中 的 export命令
  6. 算法学习(八)——排序算法汇总
  7. 【LeetCode】1652. 拆炸弹(C++)
  8. Android-进阶教程-权限-安装时权限-签名权限-signature|privileged
  9. 北京燕化附中2021年高考成绩查询,2021年北京最好的高中排名,北京重点高中排名榜公布...
  10. ITIL学习(六)服务战略之战略制定