nodejs基础(1)
nodejs
环境变量 带 cmd 下 set 有变量的名称和 变量的值
基础全局变量
全局对象 global 本质上 window 就是拓展自 global 对象
console 等模块
__dirname 当前文件所在的目录 这个是一个全局变量
__filename 当前文件的所在目录
事件循环 EventLoop
nodejs 是单线程的
任务进入执行栈
判断是同步还是异步任务
同步任务进入主线程中 然后执行
异步任务进入到一个 event table 异步事件表
在异步事件表中注册回调函数 event queue 事件队列
主线程任务执行完毕 读取任务队列的结果 然后进入主线程执行
console.log(1) settimeout(()=>{ console.log(2) }1000) console.log(3) # 如果在没有settimeout 的时候在执行打印3 后js就会退出程序 # 如果在存在settimeout,这个异步的时候,会主线程中执行打印 1 3 ,而异步任务settimeout 放到事件循环中 然后再主线程全部结束后 执行异步事件循环 ,再执行异步事件循环过程中 1进入循环检查loop 是否存活 不存活直接退出, #存活 timer 再这个阶段处理所有的settime out 等定时器的异步监视定时器的时间到达 # 然后进入 pending i/o callback 网络读写等的异步任务 第一阶段 pending 阶段,然后 idle prepare 内部阶段 poll 轮询阶段 这个阶段会可能有阻塞 这个阶段有超时控制 # 然后 check 阶段 处理 setImmediate 的回调函数 这个是新增的一个函数 #处理关闭接阶段关闭IO 关闭settimeout 等等 #如果 异步函数不存活直接退出 如果存活直接进入下一个循环。u也就是哦查看是否全部完成。
1
2
3
4
5
6
7
8
9
10
11
12
宏任务与微任务
宏任务就是 主体的 script settimeout 和 setinterval
微任务就是 promise process.nextTick
时间循环过程中先执行宏任务,宏任务执行完毕后看有没有可执行的微任务 如果有则执行微任务,然后进入下一个循环
也就是说 promise 再不是 then 或者 catch 阶段是同步的
首先区分 是同步还是异步 然后区分事件循环主次排列 任务推进主线程执行的过程中分未宏任务(先)和微任务(后)
模块化系统
commonjs 规范
定义模块
- 一个文件就是一个独立的模块
- 模块加载使用同步模式
- 通过 require 函数导入 exports 对象导出
- 每一个模块都有一个自己的独立的作用域---模块作用域
导入模块
require()内部接受模块的 ID 或是模块的路径
被导入的文件会自动执行,
被导入的文件变量之间不会互相冲突
node 可以把内部私有的数据挂载到全局对象下面这样导出都可以访问,但是这种做法并不推荐 因为污染全局变量,不会被垃圾回收期回受占用内存消耗资源。
require 方法就收的就是 exports 导出的返回值
模块导出
把要导出的挂载到 exports 对象上。
exports 对象其实是 module.exports 的封装
module 包含了很多属性
id 当前模块的唯一标识符 默认 ID 为当前的文件的绝对路径
exports 导出对象
parent 被引入的文件是子文件 而引入的则为父模块
filename 当前文件的文件路径加名称
loaded 是否已经加载完成
children 引入文件的子集
paths
模块化的分类
- 文件机制
- 文件夹作为 node_modules 的加载机制,当导入的是一个文件夹的时候就会触发文件夹导入模块,自动导入该文件夹下 index.js 可以指定文件夹的 package.json {name:'',main:''}name 是文件夹的名称 main 是文件夹的入口文件,如果导入的是 node_modules 下的只需要写文件夹的名称。
- 全局文件夹模式,node 安装的额时候自动创建一个文件夹,所有的都可以用。安装的额时候指令-G 就可以安装到全局。
- 核心文件夹模式,node 已经再安装过程已经转杯好的模块,内置模块。
- 同名优先级 1 内置模块 2 自定义 3 node_modules
- 文件处理机制 同名优先加载 1 js 2 json 3 .node
es6 的模块化
- 开启 es6 模块化
- 导入 imports {对象解构赋值} from ‘’ imports aaa as bbb from ‘’
- export 导出 export default 111 不需要起名字 直接默认导出,每个模块只能默认导出一个
- import 和 export 只能在 js 顶级域内不可以放在局部。
Stream 流
这个是一个抽象的接口 集体的实现由模块实现 流的基本类型
Writable 可写流 .write(chunk,编码,回调)写 .end(chunk,编码,回调)结束 .setDefaultEncoding(编码)设置编码 事件
readable 可读流 读取流 setEncoding 设置编码 read([size])读取方法 pipe() 开启管道 pause 暂停 resume 恢复
Duplex 可读可写流 (net.socket 基于这个实现)双工数据流
transfrom 可修改的双共数据流
Buffer
Buffer.alloc(size,fill,encoding) 分配一个大小 size 字节的缓存区 Buffer 取值也可以向一个数组一样根据下标进行,长度表示的是字符长 字节长 Buffer.from() 从其他的格式转换成 Buffer Buffer.fill(data,start,end,encoding)填充 用数据填充一个 buffer buffer.write(string,start,length,encoding) 写入数据 buffer.includes(value,byteoffset,encoding) 写入数据 是否包括 buffer.index() 某一个字节的下标 buffer.compare()比较两个 buffer 大小 buffer.equal()比较两个 buffer 数据是否相同
filesystem
fs.read 文件的读 fs.readFile() fs.write 文件的写 fs.writeFile() fs.appendFile() 在已有文件内部追加文件 fs.stats 文件的属性 创建 修改时间等等 fs.unlink()删除文件 fs.mkdir()创建文件夹 不会进行递归创建 fs.rmdir()移出文件夹 不能删除非空文件夹 fs.readdir() fs.readdirSync()读取文件夹 fs.rename()重命名文件 fs.watch(filename,options,listener)监听文件或者目录的状态变化的 listener 由两个 参数 1 eventtype 2 filename fs.watchFile(filename,options,listener) 用来监听文件的数据的变化 fs.copyfile() fs.stats 文件的信息 fs.open() 打开一个文件 返回一个文件的描述符 这个文件描述符可以被用作 其他读写操作的第一个参数 也就是其他方法中的第一个参数 fd
fs.writeFile(file, data, options, callback)
//file 是文件名称或者路径 string Buffer URL 等等 data 数据 options 选项(1.编码 2 文件权限mode 3 支持的文件系统 callback 回调
fs.appendFile(file, data, options, callback)
# 追加由属性叫flag 模式标记
fs.readFile()
const aa= fs.stats('文件路径')
aa.isFile()
#删除文件夹同步版
function rmdir(dirpath) {
if (!dirpath) return
let dir = fs.readdirSync(dirpath)
for (let i = 0; i < dir.length; i++) {
const childrenPath = `${dirpath}/${dir[i]}`
if (fs.statSync(childrenPath).isDirectory()) {
rmdir(childrenPath)
} else {
fs.unlinkSync(childrenPath, function (err) {
if (err) return false
})
}
}
fs.rmdirSync(dirpath, function (err) {
if (err) {
return false
}
})
return true
}
#fs.watch()
fs.watch('./a',
{
persistent:true ,#默认是true 如果文件被监视 进程是否继续运行
recursive:true,#是否监听子文件文件夹 默认是false
encoding:'utf8'
},
(rename或者是change)=>{
#rename 会在删除 新增文件 或改名文件的时候触发
#change 会在增删改文件内容的时候触发
}
)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
文件模块在 10.0 版本后增加很多基于 promise 实现的文件的操作方法,不在需要回调函数。 在 class filehandle 模块下
let fd = filehandle.fd()
filehandle.read(buffer, offset, length, position).then(data => {
console.log(data)
})
2
3
4
process 模块
这个模块是一个全局的对象不需要 require ,这个模块中包含了启动 node 的时候带有的参数 .argv 用来获取当前 node 进程相关参数 可以获取命令中的一些参数 使用方法在命令写参数在 process.argv[]中获取出来 .env 环境变量 设置在不同的环境 .exit([code]) 退出 当在某个阶段的时候让程序退出 .cwd 当前程序的工作目录 ,memoryUsage 程序对当前内存使用情况 getUid 获取当前程序的 Uid
标准输出流 process.stdout .write(data,encoding,callback) 数据 编码 回调 标准输入流 process.stdin.on('') data 监听输入的数据
process 的命令行拓展工具 1 commander 2 chalk(命令行的美化) 3 Inquirer 命令行的箭头选择
events 模块
这个模块是 nodejs 的核心模块 nodejs 中大部分模块都使用了或者继承了这个模块。事件绑定函数 这个模块中又个核心类 EventEmmiter .emit(eventName ,参数) 触发 .addlistner(eventName,listener) 绑定 .prependListener 在所有的绑定事件最前面绑定一个事件 .on(evenetName,listener) 绑定 .off(eventName,listener)移除 .removeListner(eventName,listener) 移除 .removeAllListener 移出所有 .eventsNames() 当前对象下面所有的被监听的事件 默认情况下一个事件最多支持 10 个监听器
const EventEmmiter = require('events')
class Persion extends EventEmmiter {
constructor(name, age) {
super()
this.name = name
this.age = age
}
groupUp() {
setInterval(() => {
console.log(this.age++)
this.emit('zg') //触发长高事件
}, 1000)
}
}
const p1 = new Persion('hahah', '18')
p1.addListener('zg', () => {
//绑定事件
console.log('啊 长高了~')
})
p1.groupUp()
//18 啊 长高了~ 19 啊 长高了~ 20 啊 长高了~
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
events 最大的作用是在异步事件的钩子 或者开发模块化