一、包
1、包的定义
包规范允许我们将一组相关的模块组合到一起,形成一组完整的工具。
包规范由 包结构 和 包描述文件 两个部分组成。包结构用于组织包中的各种文件。包描述文件:描述包的相关信息,以供外部读取分析。
2、包结构
包实际上就是一个压缩文件,解压以后还原目录。符合规范的目录,应该包含如下文件:
package.json 描述文件
bin 可执行二进制文件
lib js代码
doc 文档
test 单元测试
3、包描述文件
(1)package.json
package.json 项目描述文件,记录了当前项目信息,例如项目名称、版本、作者、github地址、当前项目依赖了哪些第三方模块等。
package-lock.json文件的作用:锁定包的版本,确保再次下载时不会因为包版本不同而产生问题。加快下载速度,因为该文件中已经记录了项目所依赖第三方包的树状结构和包的下载地址,重新安装时只需下载即可,不需要做额外的工作。
(2)项目依赖和开发依赖
项目依赖:在项目的开发阶段和线上运营阶段,都需要依赖的第三方包,称为项目依赖。
使用npm install 包名命令下载的文件会默认被添加到 package.json 文件的 dependencies 字段中。
开发依赖:在项目的开发阶段需要依赖,线上运营阶段不需要依赖的第三方包,称为开发依赖。
使用npm install 包名 --save-dev命令将包添加到package.json文件的devDependencies字段中。
二、npm
npm 帮助Node完成了第三方模块的发布、安装和依赖等。借助NPM,Node与第三方模块之间形成了很好的一个生态系统。
1、初始化包的描述文件
(1)npm init 需要手动输入包的描述信息
(2)npm init -y 包的描述信息全部采用默认设置
2、npm的常用命令
(1)下载包
备注:install的简写是i,--save的简写是-S,--save-dev的简写是-D,--global的简写-g。
npm install 包名 下载包 (默认会将下载的包添加到生产环境依赖,生产环境依赖的包参与本项目的打包)
npm install 包名 --save (--save表示下载包,并添加到生产环境依赖)
npm install 包名 --save-dev (--save-dev表示下载包,并添加到开发环境依赖,只是开发时依赖该包,不参与本项目的打包)
npm install 包名 --global 安装全局插件
使用npm下载第三方包后,会在项目根路径中添加一个package-lock.json文件。该文件是可以删除的,它的作用是记录第三方包的完整信息,方便下次下载包时快速定位该包的信息,省去了查找包的时间。
(2)升级包
npm update 包名 对指定包进行升级
npm update 升级所有包
(3)删除包
备注:remove的简写是r
npm remove 包名 移除包
npm uninstall 包名 卸载包(功能等同于移除包)
(4)下载所有依赖包
npm install/i 根据package.json文件中的依赖关系,下载当前项目所依赖的包
4、npm镜像地址
(1)查看npm镜像地址
npm config get registry
(2)修改npm镜像地址
方式①:直接编辑npm的配置文件
npm config edit
直接修改registry的地址:
registry=https://registry.npm.taobao.org/
方式②: 用代码更改npm的配置文件
这段代码就是将镜像改为淘宝镜像:
npm config set registry https://registry.npm.taobao.org
方式③:使用nrm管理registry地址
## 安装nrm
npm install -g nrm
## 查看镜像列表
nrm ls
# nrm ls 报错解决方案:
#// const NRMRC = path.join(process.env.HOME, '.nrmrc');(注释掉)
const NRMRC = path.join(process.env[(process.platform == 'win32') ? 'USERPROFILE' : 'HOME'], '.nrmrc');
## 切换镜像
nrm use taobao
## 在nrm添加自己的镜像地址
nrm add r_name r_url
## 删除
nrm del r_name
## 测试镜像的相应速度
nrm test r_namer
(3)还原npm原来的镜像地址
npm config set registry https://registry.npmjs.org/
三、cnpm中国 npm 镜像客户端
1、安装cnpm
npm install cnpm -g
2、cnpm命令
cnpm的所有命令跟npm一样。(唯一的区别是:cnpm install 包名,不会将下载的包默认添加到生产环境依赖。必须要加上--save。)
四、yarn
1、安装yarn包管理工具
方式(1) 使用npm安装
npm install yarn -g
方式(2) 使用安装包安装
官方下载安装包,安装完毕后,一定要配置环境变量。
2、yarn镜像地址
(1)查看yarn镜像地址
yarn config get registry
(2)修改yarn镜像地址
yarn config set registry http://registry.npm.taobao.org/
(3)还原yarn原理的镜像地址
yarn config set registry http://registry.npmjs.org/
3、yarn的常用命令
(1)下载所有依赖包
注意:npm中install,可以简写成i,yarn中不可以;但是yarn可以省略install。
yarn install === npm install
(2)下载包
注意:--save可以省略,因为默认就是添加到生产依赖。
yarn add 包名 === npm install 包名 --save
yarn add 包名 --dev === npm install 包名 --save-dev
注意:npm中--global可以简写成-g。
yarn global add 包名 === npm install 包名 --global
(3)删除包
注意:npm中remove,可以简写为r,yarn中不可以。
yarn remove 包名 === npm remove 包名
(4)升级包
yarn upgrade 包名 === npm update 包名
yarn upgrade === npm update
五、文件系统
1、文件系统
文件系统(File System)简单来说就是通过node来操作系统中的文件。
使用文件系统,需要先引入fs模块,fs是核心模块,直接引入不需要下载。
let fs = require('fs')
fs模块中所有的操作都有两种形式可供选择:同步和异步。
同步文件系统会阻塞程序的执行,也就是除非操作完毕,否则不会向下执行代码。
异步文件系统不会阻塞程序的执行,而是在操作完成时,通过回调函数将结果返回。
2、同步方式读取文件
同步方式读取文件,指的是文件的读取过程必须是一个一个读取。假如,后面还要读取其他文件,必须要等到前面的文件读取完成了,再读取下一个文件。
方法(1)读取文件 openSync/readSync/closeSync
① 打开文件
通过openSync方法打开文件,返回值是文件标识(文件标识是一个数字)
let fd = fs.openSync('./file/a.txt','r')
② 读取文件中的内容
通过readSync方法读取文件。参数1:文件标识;参数2:buffer容器。
创建一个buffer容器,用于接收读取到的数据,其实就是开辟一段内存空间(单位是字节)。注意:一个汉字占用三个字节空间。
let buf = Buffer.alloc(30) // 创建30字节的buffer容器
fs.readSync(fd,buf) // 用buf接收fd文件数据
③ 关闭文件
文件读取结束后,需要关闭文件
fs.closeSync(fd) // 关闭fd文件
方法(2)一般方式读取文件 readFileSync()
fs.readFileSync(文件路径)
let buf = fs.readFileSync('./file/a.txt')
console.log('同步:'+buf.toString());
3、同步方式写入文件
同步方式写入文件的缺陷:如果要写入多个文件,只能一个一个写。
方法(1)写入文件 openSync/writeSync/closeSync
① 打开文件
通过openSync方法打开文件,返回值是文件标识(文件标识是一个数字)。
参数1:文件路径,
参数2:打开文件的方式:r是读,w是写,a是追加。
let fd = fs.openSync('./file/b.txt','a')
② 向文件中写入内容
如果需要写入中文,加一个'utf-8';内容是纯英文可以省略。
fs.writeSync(fd,'HelloWorld你好','utf-8')
fs.writeSync(fd,'HelloWorld')
③ 关闭文件
文件写入后,需要关闭文件。
fs.closeSync(fd)
方法(2)一般方式写入文件 writeFileSync()
writeFileSync()方法内部已经完成了文件的打开、读取、关闭操作。
try{
fs.writeFileSync('./file/a.txt','HelloWorld',{flag:'a'}) // 追加参数a要写在对象中
console.log('同步:写入成功!');
}catch{
console.log('写入失败!');
}
4、异步方式读取文件
异步方式读取文件,采用的都是回调函数的形式,相比较同步方式,代码量变复杂了。优势是,可以同时操作多个文件。
方法(1)读取文件 open/read/close
// 01.打开文件
fs.open('./file/a.txt',(err,fd)=>{
// 回调函数的两个参数分别是:错误信息,文件标识,如果能够打开文件,错误信息为null
if(!err){
// 02.读取文件中的内容
fs.read(fd,(err,num,buf)=>{
// 回调函数的三个参数分别是:错误信息,读取文件的字节数,buffer内容
if(!err){
console.log('读取了'+num+'个字节');
console.log('内容是:'+buf.toString());
}
// 03.文件读取结束后,需要关闭文件
fs.close(fd,(err)=>{
if(!err){
console.log('文件读取完毕!');
}
})
})
}
})
方法(2)一般方式读取文件 readFile()
readFile方法内部,帮我们完成了文件的打开,读取,关闭操作。
fs.readFile('./file/a.txt',(err,buf)=>{
if(!err){
console.log('异步:'+buf.toString());
}
})
5、异步方式写入文件
方法(1)写入文件 open/read/close
// 01.打开文件
// 参数1:文件位置
// 参数2:打开文件的方式,r是读,w是写,a是追加
fs.open('./file/b.txt','a',(err,fd)=>{
if(!err){
// 02.向文件中写入内容
fs.write(fd,'HelloWorld',(err)=>{
if(!err){
// 03.文件写入后,需要关闭文件
fs.close(fd,(err)=>{
if(!err){
console.log('写入成功!');
}
})
}
})
}
})
方法(2)一般方式写入文件 writeFile()
fs.writeFile('./file/b.txt','HelloWorld',{flag:'a'},(err)=>{
if(!err){
console.log('异步:写入成功!');
}
})
六、同步API和异步API
1、同步API
同步API:只有当前API执行完成后,才能继续执行下一个API。
同步API,可以通过返回值接收结果。
// 同步API
function fun1(){
return '大家好!我是一个同步方法'
}
// 同步API,可以通过返回值接收结果
let str1 = fun1()
console.log(str1); // str1
2、异步API
异步API:当前API的执行不会阻塞后续代码的执行。
异步API时,直接写一个回调函数作为参数传进入,这个函数接收异步API返回值。
// 异步API
function fun2(callback){
setTimeout(() => {
callback('大家好!我是一个异步方法')
}, 1000);
}
// 调用异步API时,直接写一个回调函数作为参数传进入。
// 回调函数,通常会写成箭头函数
fun2(str => console.log(str))
3、同步API和异步API的区别
(1)同步API可以从返回值中拿到API执行的结果,但是异步API是不可以的。
(2)同步API从上到下依次执行,前面代码会阻塞后面代码的执行;异步API不会等待API执行完成后再向下执行代码。
4、回调函数
自己定义函数让别人去调用。
// getData函数定义
function getData (callback) {}
// getData函数调用
getData (() => {});
// 使用回调函数获取异步API执行结果
function getMsg (callback) {
setTimeout(function () {
callback ({ msg: 'Hello Node.js' })
}, 2000);
}
getMsg (function (msg) {
console.log(msg);
});
七、try..catch
将可能会发生异常的代码放在try中,如果程序发生异常,会跳转到catch中执行保护代码,
使程序不至于就此终止。catch代码块可以传递一个参数e,里面保存的是发生异常的消息。
// 文件系统在实际开发中的用法:
try{
let num1 = 10
let num3 = num1 + num4
console.log(num3);
}catch(e){
//通常情况下,需要将错误信息写入到日志文件中
// console.log('上面的代码发生了错误',e.message);
fs.writeFile('./file/log.txt',e.message+' 发生时间:'+(new Date())+'\r\n',{flag:'a'},(err)=>{
if(!err){
console.log('错误信息,写入日志文件');
}
})
}
八、Promise 对象
1、语法
Promise出现的目的是解决Node.js异步编程中回调地狱的问题。
Promise的构造函数接收一个参数,是函数,并且传入两个参数:resolve、reject,分别表示异步操作执行成功后的回调函数和异步操作执行失败后的回调函数。
Promise对象的then()方法用来获取成功的返回结果;catch()方法用来获取失败的返回结果。
function myReadFile(path) {
return new Promise((resolve) => {
fs.readFile(path, (err, r) => {
if (!err) {
resolve(r.toString())
}
})
})
}
myReadFile('./file/a.txt').then(r => {
if (r == '中国') {
return myReadFile('./file/e.txt')
}
}).then(r => {
if (r == '赛虹桥街道') {
console.log(r);
}
})
2、async和await
async关键字,用于定义异步函数,异步函数中,可以使用await关键字,简化then的步骤。await关键字提取Promise对象的返回的结果。
(1)async关键字
① 普通函数定义前加async关键字,普通函数变成异步函数
② 异步函数默认返回promise对象
③ 在异步函数内部使用return关键字进行结果返回,结果会被包裹到promise对象中,return关键字代替了resolve方法。
④ 在异步函数内部使用throw关键字抛出程序异常
⑤ 调用异步函数再链式调用then方法获取异步函数执行结果
⑥ 调用异步函数再链式调用catch方法获取异步函数执行的错误信息
(2)await关键字
① await关键字只能出现在异步函数中
② await promise:await后面只能写promise对象,写其他类型的API是不可以的
③ await关键字可以暂停异步函数向下执行,直到promise返回结果
(3)应用
async function run() {
let a = await myReadFile('./file/a.txt')
if (a != '中国') return
let e = await myReadFile('./file/e.txt')
if (e != '赛虹桥街道') return
console.log(e);
}
run()
网友评论