笔记
nodejs
进程与线程
node的用途
- Web服务API,比如REST
- 实时对人游戏
- 后端的web服务,例如跨域服务端的请求
- 基于web的应用
- 多客户端的通信,如即时通信
# 在node中一个js就是一个模块
# 引入其他模块
# 在node中,通过required(路径)函数引入外部模块
# 路径:使用相对路径必须以. 或 ..开头,不使用的话,代表引入的为核心模块
模块声明
引入的模块会返回一个对象,使用变量进行接收
var o1 = require("./01.js")
- 在node中每个js都是独立运行的函数,相互之间隔离,而不是全局作用域,所以一个模块中的变量和函数,其他模块无法
- 可以使用exports将模块内部的变量函数暴露提供外部使用
/*01.js中内容*/
exports.x="01.js中的变量"
exports.add=function (a,b){
return a+b;
}
exports.mul=function (a,b){
return a*b;
}
模块引入
/*引入模块*/
var o1 = require("./01.js")
console.log(o1);
console.log(o1.add(199,200));
console.log(o1.mul(199,200));
# 输出
01Module.js
{
x: '01.js中的变量',
add: [Function (anonymous)],
mul: [Function (anonymous)]
}
399
39800
模块标识
模块分为两大类
- 核心模块
- 文件标识,就是模块的我、名字
- 文件模块
- 用户自己创建的模块,文件模块的标识就是,文件创建的路径(绝对路径,相对路径 . 或 … )
node全局对象
在node中有一个全局对象global, 它的作用和网页中的window类似,
在全局中创建的属性作为global的属性保存,
在全局中创建的函数作为global的函数保存,
a="声明全局属性不写var"
b=function (){
return"全局函数!";
}
console.log(global.a);
console.log(global.b());
证明模块是运行在一个模块中的
# arguments参数结构
[Arguments] {
'0': {},
'1': [Function: require] {
resolve: [Function: resolve] { paths: [Function: paths] },
main: Module {
id: '.',
path: 'D:\\Document\\webStorm\\2021\\0208\\01.node',
exports: {},
parent: null,
filename: 'D:\\Document\\webStorm\\2021\\0208\\01.node\\03.js',
loaded: false,
children: [],
paths: [Array]
},
extensions: [Object: null prototype] {
'.js': [Function (anonymous)],
'.json': [Function (anonymous)],
'.node': [Function (anonymous)]
},
cache: [Object: null prototype] {
'D:\\Document\\webStorm\\2021\\0208\\01.node\\03.js': [Module]
}
},
'2': Module {
id: '.',
path: 'D:\\Document\\webStorm\\2021\\0208\\01.node',
exports: {},
parent: null,
filename: 'D:\\Document\\webStorm\\2021\\0208\\01.node\\03.js',
loaded: false,
children: [],
paths: [
'D:\\Document\\webStorm\\2021\\0208\\01.node\\node_modules',
'D:\\Document\\webStorm\\2021\\0208\\node_modules',
'D:\\Document\\webStorm\\2021\\node_modules',
'D:\\Document\\webStorm\\node_modules',
'D:\\Document\\node_modules',
'D:\\node_modules'
]
},
'3': 'D:\\Document\\webStorm\\2021\\0208\\01.node\\03.js',
'4': 'D:\\Document\\webStorm\\2021\\0208\\01.node'
}
//输出arguments
console.log(arguments+"");
//arguments.callee这个属性保存的是当前执行的函数对象
//+""加上一个字符创,向相当于toString,查看函数结构
输出
a="声明全局属性不写var"
b=function (){
return"全局函数!";
}
console.log(global.a);
console.log(global.b+"");
//arguments.callee这个属性保存的是当前执行的函数对象
console.log(arguments.callee+"");
}
node在执行模块中的js代码时,会将模块中的代码使用一个函数惊醒包裹起来
function (exports, require, module, __filename, __dirname) {
}
现在看来我们所使用的exports,require并不是全局属性,而是传入的参数
-
exports:该对象用于暴露出的属性或函数
-
require:导入模块
-
moudle:代表当前模块本身,exports就是moudle的属性,既可以使用exports,也可以使用moudle.exports导出
-
_filename:当前模块的完成路径名
-
_dirname:当前模块所在的文件夹路径
exports与moudle.exports的区别
# 可以导出对象
module.exports = {
x: "01.js中的变量",
add: function (a, b) {
return a + b;
},
mul: function (a, b) {
return a * b;
}
}
# 不可以导出毒性,次写法调用不到
exports = {
x: "01.js中的变量",
add: function (a, b) {
return a + b;
},
mul: function (a, b) {
return a * b;
}
}
为什么?
exports执行的就是module.exports,是他的一个引用类型,为这个对象中的值定义,两个属于共享,而当为exports赋值为一个对象时,就代表着exports不再指向module.exports了,所以就无法导出
node包介绍
-
Commonjs的包规范允许我们将一组相关的模块组合到一起,行程一组完整的工具,
-
CommonJS的包规范由包结构和包描述文件两个部分组成。
-
包描述文件用于表达非代码相关的信息,他是一个json格式的文件-package.json,位于包的根目录下,是包的重要组成部分。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GEIDj68P-1613224309230)(D:\Document\TyperImages\image-20210210145227150.png)]
- package.json中的字段
- name,description,verson,keywords,maintainers,contrubutors,bugs…
npm 常用命令
# npm search 包名 //搜索包
# npm init //初始化,创建package.json文件
# npm -v //查看版本
# npm verison //查看所有模块的版本
# npm install/i 包名 //安装包
# npm remove/r 包名 //移除包
# npm install 包名 --save //--save向package.json中保存dependencys描述信息,新版npm不添加--save也可以保存
# npm install //从package.json的dependencys中的描述依赖下载包
# npm install 包名 -g //-g 全局安装,(一般都会将工具全局安装)
- node在使用模块名字来引入模块时,他会首先在当前目录的node_moudles中寻找是否含有该模块,如果有则使用,如果没有则去上一级目录寻找,一直向上寻找,直到磁盘的根目录,再找不到就报错
Buffer(缓冲区)
-
buffer的结构和数组很像,操作的方法也和数组类似
-
数组中不能存储二进制的文件,而buffer就是专门用来存储二进制数据的
-
使用buffer不需要引入模块,直接使用即可
-
在buffer中存储的都是二进制数据,但是显示时时以16进制的形式来展示
buffer中每一个元素的范围都是从00 - ff 0 - 255 00000000 - 11111111 计算机 一个0或一个1我们称为1位(bit) 8bit = 1byte(字节) 1024byte = 1kb 1024kb = 1mb ... buffer中的一个元素,占用内存的一个字节 存储中文,根据不同的字符编码,中文所占用的字节也不同,Unicode中文占用3个字节,utf-8占用2个字节
var str=",hell!缓冲区"; var buf = Buffer.from(str); console.log(buf); console.log(buf.length);//所占用内存的大小 console.log(str.length)//长度 //创建一个指定大小的Buffer var buf2 = Buffer.alloc(10); //使用allocUnsafe()指定内存大小时,可能会有铭感数据,只分配空间,不清楚数据 //alloc()分配空间并清楚数据 buf2[0]=123; buf2[1]="123"; buf2[2]=0x23; buf2[3]=255; buf2[4]=256; console.log(buf2[0]); console.log(buf2[1]); console.log(buf2[2]); console.log(buf2[3]); console.log(buf2[4]);
文件系统(File System)
- 文件系统简单来说就是通过node来操作系统中的文件
- 使用文件系统,需要引入fs模块,直接引入即可,无需下载
同步文件的操作
-
手动操作的步骤
-
打开文件
fs.openSync(path,flsgs[,model]);
-
path:文件所在路径
-
flags:标志对文件的操作(r,w 读,写)
-
model设置问价的操作权限,一般不传
返回值
- fs.openSync(“hello.txt”,“w”);该方法会返回一个文件的描述符作为结果,我们可以通过该描述符来对文件进行各种操作
-
-
向文件中写入内容
fs.writeSync(fd,String,position);
fd:问价描述符
string:写入的内容
position:预留出来的位置
-
保存并关闭文件
fs.closeSync(文件描述符);
-
let fs = require("fs");
let hello = fs.openSync("hello.txt","w");
console.log(hello);
//写入内容
fs.writeSync(hello,"今天心情很糟糕!",5);
//释放文件
fs.closeSync(hello)
异步文件操作
//1.打开文件
fs.open("hello2.txt","w",function(err,fd){
if(!err){
//2.写入文件
fs.write(fd,"今天心情很不好!",function (err) {
if(!err){
console.log("写入成功");
}
})
//3.关闭
fs.close(fd,function (err) {
if(!err){
console.log("关闭成功!")
}
})
}else{
console.log(err);
}
});
- fs.open(文件路径,操作标志[,model权限],回调函数);
- fs.write(文件描述符,写入内容,[,position],回调函数);
- fs.close(文件描述符,回调函数);
简单文件操作
- fs.writeFile(file,data[,options],callback)
- fs.writeFileSync(file,dafam[,options],callback)
- file 要操作的文件的路径
- data 要写入的数据
- options 选项,可以对写入进行一些设置
- callback 回调函数,写入完成执行的函数
let fs = require("fs");
//fs.writeFile(file,data[,options],callback)
fs.writeFile("hello3.txt","现在已经凌晨12点了",{flag:"w"},function (err){
if(!err){
console.log("写入成功!");
}
})
flag取值
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wiP4kv3m-1613224309232)(D:\Document\TyperImages\image-20210211000852503.png)]
流式文件操作(适用大文件)
//导入fs
let fs = require("fs");
//文件不存在就创建,存在就会覆盖
//path:路径
//最高水位线默认16k
//默认utf-8字符编码
//options:配置的参数
let writeStream = fs.createWriteStream("liushiwenjian.txt");
//可以通过监听open和close事件来监听流的打开与关闭
/*
on(事件字符串,回调函数)
- 可以为对象绑定一个事件
once(事件字符串,回调函数)
- 可以为对象绑定一个一次性的事件,改事件会在触发一次以后自动失效
*/
writeStream.once("open",function (){
console.log("文件打开了");
})
writeStream.once("close",function (){
console.log("文件打开了");
})
// write是异步方法,有返回值,每次调用write方法会返回布尔值
//write里面只能是字符串或buffer
//返回值是true表示能继续写入,如果为false就不要继续写入
writeStream.write("aa");
writeStream.write("bb");
writeStream.end();//结束,如果调用end,会强制将内存中的内容全部写入,然后关闭文件
//监控内存里面全部写完了,恢复读取,才会调用此方法
writeStream.on('drain',function () {
console.log("内存干了");
});
文件简单读取
let fs = require("fs");
//path,callback 错误信息,读取到的数据
fs.readFile("timg (2).jpg",function (err,data) {
//读取的数据为二进制,使用toString()方法来转换显示
console.log(data)
//将读取出的数据写出
let writeStream = fs.createWriteStream("tp.jpg");
//文件写出
writeStream.write(data);
writeStream.end();
})
流式文件读取(适用大文件)
//使用与大文件操作
//引入fs模块
let fs = require("fs");
//创建一个可读流
let rs = fs.createReadStream("tp.jpg");
//创建一个可写流
let ws = fs.createWriteStream("tp2.jpg");
//监听开启和关闭
rs.once("open",function () {
console.log("可读流打开了。。。")
});
rs.once("close",function () {
console.log("可读流关闭了。。。");
//在可读流数据读取完毕后关闭后,关闭可写流
ws.end();
});
ws.once("open",function () {
console.log("。。。可写流打开了")
});
ws.once("close",function () {
console.log("。。。可写流关闭了")
});
//读取
//如果要读取一个可读流中的数据,必须要为可读流绑定一个data事件,data事件绑定完毕,它会自动打开开始读取数据
rs.on("data",function (data) {
//console.log(data.length);
ws.write(data);
})
//使用pipe直接将读和写链接在一起,替代data事件
rs.pipe(ws);
peie
//使用pipe直接将读和写链接在一起,替代data事件
rs.pipe(ws);
Node 操作数据库
var mysql = require("mysql");
var connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: '123456',
database: 'blog'
});
connection.connect();
connection.query('select * from tb_user', function (error, results, fields) {
if (error) throw error;
for (let i=0;i<results.length;i++){
console.log(results[i]);
}
});
connection.end();
https://www.runoob.com/nodejs/nodejs-mysql.html