【前端开发-----NodeJS】nodejs快速入门教程,想要快速入门nodejs就看这一篇文章就够了,基础部分特详细,按要点整理知识点
nodejs 中API的特点
- 最后一个参数是callback
- 同步方法会阻塞主线程,虽然有callback方法,没有实际作用
方法名('参数1','配置项',callback(err,data){
if(err) throw err
// data:返回的结果
})
- 可监听
const result = 方法('参数','配置项')
result.on('data',(res)=>{
// res:执行结果
})
result.on('close',()={
// 执行完毕,结果也全部返回
})
- promise版
promise('命令').then(res=>{
// 命令执行成功后的结果
}).catch((err)=>{
// 异常
})
1. path
const path = require('path');
// 简单的把参数拼接为路径
console.log(path.join("a","b")) // a\b
// 返回的必须是根路径,没有给定根路径就拼接了当前目录的路径,我不知道它怎么做到的
console.log(path.resolve("a","b")) // D:\vue\code\node\nodejs-xuexi\a\b
// 给定根路径,返回的是从盘符开始的
console.log(path.resolve("/a","b")) // D:\a\b
// 正常是结合__dirname使用的
console.log(path.resolve(__dirname,"b","c")) //D:\vue\code\node\nodejs-xuexi\b\c
// 返回文件的路径
console.log(path.dirname("a/b/c/index.js")) // a\b\c
// 返回文件的文件名
console.log(path.basename("a/b/c/index.js")) // index.js
// 返回文件的后缀
console.log(path.extname("a/b/c/index.js")) // .js
// 将路径转为对象形式
console.log(path.parse("a/b/c/index.js")) // { root: '', dir: 'a/b/c', base: 'index.js', ext: '.js', name: 'index' }
// 与parse想对应,将对象形式转为字符串形式
console.log(path.format({ root: '', dir: 'a/b/c', base: 'index.js', ext: '.js', name: 'index' })) // a/b/c\index.js
2. 全局变量
1. 原生的全局变量
- __dirname:当前文件的绝对路径
- __filename:当前文件的带有路径的文件名
console.log(path.join(__dirname)) // D:\vue\code\node\nodejs-xuexi
console.log(path.join(__filename)) // D:\vue\code\node\nodejs-xuexi\index.js
2. 定义全局变量
- ECMAScript 2020 出现了一个globalThis全局变量,在nodejs环境会自动切换成global ,浏览器环境自动切换window非常方便
3. os
const os = require('os');
// 操作系统类型
console.log(os.type()) // windows_NT
// 操作系统平台
console.log(os.platform()) // win32
// CPU架构
console.log(os.arch()) // x64
// 系统版本
console.log(os.release()) // 10.0.19041
// 系统正常运行时间
console.log(os.uptime()) // 7405.656
// CPU信息:架构、型号、速度、缓存等
console.log(os.cpus()) // 获取CPU信息
// 系统内存总量(单位:字节)
console.log(os.totalmem()) // 34284859392
// 系统剩余内存(单位:字节)
console.log(os.freemem()) // 23526678528
// 用户的主目录,在window中返回的是 %USERPROFILE%
console.log(os.homedir()) // C:\Users\Administrator
// 网络信息
console.log(os.networkInterfaces())
console.log(os.machine()) // x86_64
4. process 进程
// 返回一个数组,其中包含启动Node.js进程时传递的命令行参数。
console.log(process.argv)
/*
[
'C:\\Program Files\\nodejs\\node.exe', // node命令路径
'D:\\vue\\code\\node\\nodejs-xuexi\\process.js', // 被执行文件路径
'--open', // 获取命令后面的参数
'--xx'
]
*/
// 当前系统的环境变量,并可以临时修改系统变量,但是不会真正修改系统中的系统变量
console.log(process.env)
// 获取当前进程的进程ID
console.log(process.pid) // 2696
// cpu 架构,和os.arch()一样
console.log(process.arch) // x64
// 结束当前进程
process.exit()
// 杀死pid的进程
process.kill(进程的pid)
5. child_process 子进程
- 在node中带有Sync的方法是同步方法,会产生阻塞,非I/O(输入/ 输出)操作一般使用主线程执行
- 异步方法会在子线程中执行
- exec
// exec:返回一个完成的执行结果
// 通过cmd执行命令,返回的结果必须小于200kb
exec('dir',(error,stdout,stderr)=>{
console.log(stdout.toString());
})
// 同步执行
const menu = execSync('dir');
console.log(menu.toString());
- spawn
// spawn:执行过程中,边执行边返回
// 通过cmd执行命令,
spawn('node',['path.js'])
// 通过data和close事件监听命令执行情况
const { stdout } = spawn("node", ["path.js"]);
// stream是spawn执行返回的数据
stdout.on("data", (stream) => {
console.log("spawn执行", stream.toString());
});
stdout.on("close", () => {
console.log("spawn执行结束");
});
- execFile
// execFile:执行文件 只能执行js文件
execFile('node',['path.js'],(error,stdout,stderr)=>{
console.log(stdout.toString());
})
- fork
- 给当前进程创建子进程,并在子进程中执行文件
fork('path.js')
- 与子进程的通信:给子进程发送消息
// 主进程
const forkProcess = fork('child.js')
forkProcess.send("主进程发送的消息")
// child.js
process.on('message', function(m){
console.log('child子进程接收到的消息:', m); // child子进程接收到的消息: 主进程发送消息
})
- 与子进程通信:子进程给主进程发送消息
// 主进程
const forkProcess = fork('child.js')
// forkProcess.send("主进程发送的消息")
forkProcess.on('message', function(m){
console.log('主进程接收到的消息:', m) // 主进程接收到的消息: child子进程向父进程发送消息
})
// 子进程,child.js
// process.on('message', function(m){
// console.log('child子进程接收到的消息:', m);
// })
process.send('child子进程向父进程发送消息');
6. evnet 事件订阅
// 1. 引入
const eventEmit = require('events');
// 2. 实例
const event = new eventEmit();
// 3. 订阅
event.on('say', (data) => {
console.log(data);
})
// 4. 发布
event.emit('say','hello world');
- 关闭事件
const fn = (data) => {
console.log(data)
}
//event.once('run',fn) // 调用多次的情况下,只执行一次
event.on('run',fn)
// 关闭事件时,事件名和方法必须要与on时的一致,需要把执行的事件定义到外部
event.off('run',fn)
event.emit('run','hello world')
7. utils 工具集
1. util.promisify 把函数包装为promise
// 执行原生的exec函数
const { exec } = require("child_process");
exec('node -v',(err,stdout,stderr)=>{
if(err){
return err
}
console.log(stdout.toString())
})
// 把exec包装为promise函数
const util = require('util');
const execPromise = util.promisify(exec);
execPromise('node -v').then(data=>{
console.log(data)
}).catch(err=>{
console.log(err)
})
2. format 格式化
const util = require('util');
const formatString = util.format('%s --- %d', 'xm', 666);
console.log(formatString) //xm --- 666
8. fs 文件
Nodejs 第二十章(fs 上)
Nodejs 第二十章(fs 下)
1. 读文件
const fs = require("fs");
// 1.异步读文件,不加utf-8,data是二进制buffer
fs.readFile('file.txt','utf-8', (err, data) => {
if (err) throw err;
console.log(data);
})
// 2. 同步读文件,返回的是数据流
const stream = fs.readFileSync("file.txt", (err) => {
if (err) throw err;
});
console.log(stream.toString())
// 3. readPromise版本的读文件
const { readFile } = require("fs/promises");
readFile("file.txt").then((res) => console.log(res.toString()));
2. 目录的创建和删除
- 创建目录
const fs = require('fs')
fs.mkdir('./test', (err) => {
if (err) throw err;
})
// 递归创建目录需加参数
fs.mkdir('./test/test1/test2',{recursive:true},(err)=>{
if (err) throw err;
})
- 删除目录
// 删除目录
fs.rmdir('./test/test1/test2',(err)=>{
if (err) throw err;
})
// 有子目录的情况下,删除父目录需要递归删除
fs.rmdir('./test',{recursive:true},(err)=>{
if (err) throw err;
})
3. 改名
// 异步
fs.rename('./file.txt','file1.txt',(err)=>{
if (err) throw err;
})
// 同步
fs.renameSync('./file1.txt','file.txt')
4. 文件修改的监听
fs.watch('./file.txt',(eventType,filename)=>{
console.log('事件:',eventType,'---文件名:',filename) // 事件: change ---文件名: file.txt
})
5. 写入文件
const fs = require("fs");
// 写文件,将 Hello World 写入 hello.txt
fs.writeFileSync("hello.txt", "Hello World!");
// 上面的写入会覆盖原文件内容,如需给文件添加需要参数
fs.writeFileSync("hello.txt", "故人西辞黄鹤楼", {
flag: "a", // 这里的参数很多
});
// 原生的给文件追加内容的函数
fs.appendFileSync("hello.txt", "烟花三月下扬州");
6. 流文件
适合大文件的读写
- 读、写流文件
const readStream = fs.createReadStream("file.txt");
const writeStream = fs.createWriteStream("file1.txt");
readStream.pipi(writeStream)
- 读大文件
// 读取文件时,一段一段读,不会一次性把文件读到内存
const readStream = fs.createReadStream("file.txt");
// 监听读文件,chunk:块
// streamObj:流文件对象,对象中有流的属性和方法
// .on:开始工作并监听
const streamObj = readStream.on("data", (chunk) => {
console.log(chunk.toString());
})
// 文件读取完成后执行
readStream.on("close",()=>{
console.log("文件读取完成")
})
- 数据较大,分段写入
// 写入大量文件,分段写入
const tangshi = [
'故人西辞黄鹤楼',
'烟花三月下扬州',
'孤帆远影碧空尽',
'唯见长江天际流',
];
// 1. 创建一个可写流
const writeStream = fs.createWriteStream("file.txt");
// 2. 分段写入数据
tangshi.forEach((line) => {
writeStream.write(line);
})
// 3. 关闭流
writeStream.end();
// 4. 监听可写流
writeStream.on("finish", ()=>{
console.log("写入完成");
})
writeStream.on("error", (err)=>{
console.log(err);
})
writeStream.on("close", ()=>{
console.log("流关闭");
})
7. 判断读取到的是文件还是文件夹
fs.stat('./text',(err, data)=>{
console.log(data.isdir())
})
6. 硬链接和软连接
9. 哈希值
- md5:无论什么文件,计算后的md5值都是32位
const crypto = require('crypto')
// 使用md5加密
const hash = crypto.createHash('md5')
// const hash = crypto.createHash('sha256')
const data = 'hello world'
// 生成字符串的md5值
hash.update(data)
// 输出加密后的值,转换为16进制
console.log(hash.digest('hex')) // 5eb63bbbe01eeed093cb22bb8f5acdc3
10. zlib 压缩
- gz:适合文件压缩
- deflate:适合http响应体
1. gz
const fs = require('fs');
const zlib = require('zlib');
// 压缩文件 zlib.createGzip()
const readStream = fs.createReadStream('file.txt');
const writeStream = fs.createWriteStream('output.txt.gz'); // 注意后缀
readStream.pipe(zlib.createGzip()).pipe(writeStream);
// 解压文件
const readStream = fs.createReadStream('output.txt.gz');
const writeStream = fs.createWriteStream('output.txt');
readStream.pipe(zlib.createGunzip()).pipe(writeStream);
2. deflate
const fs = require('fs');
const zlib = require('zlib');
const readStream = fs.createReadStream('file.txt');
const writeStream = fs.createWriteStream('output.txt.deflate'); // 注意后缀
readStream.pipe(zlib.createDeflate()).pipe(writeStream);
const readStream = fs.createReadStream('output.txt.deflate');
const writeStream = fs.createWriteStream('output.txt');
readStream.pipe(zlib.createInflate()).pipe(writeStream);