node 基础
Node.js 是运行在服务端的 JavaScript
1、node交互解释器REPL
可以在终端输入node,然后进入交互解释器,然后输入命令,接受系统的响应
下划线(_)变量
下划线(_)获取上一个表达式的运算结果
.save 保存代码
.load 载入代码
2、编辑器运行代码和npm包安装
let a=3;
let b=4;
console.log(a+b);
在vscode中终端中打开,在终端中运行,控制台输出结果
npm是包管理工具
3、node 模块化
一个 Node.js 文件就是一个模块
引入模块
代码 require(’./hello’) 引入了当前目录下的 hello.js 文件
var hello = require('./hello');
Node.js 提供了 exports
和require
两个对象,其中exports
是模块公开的接口,require
用于从外部获取一个模块的接口,即所获取模块的 exports 对象。
方法一:
将需要导出的变量或者函数挂载到exports对象的属性上
//hellow.js
function hello(){
console.log("hello");
}
const we=2;
exports.world=hello;
//main.js
var hi = require('./hellow');
hi.world();
方法二:
用module.exports对象整体导出一个函数或者变量对象
格式如下:
module.exports = function() {
// ...
}
//hello.js
function fn() {
console.log("fn");
}
var we =2;
module.exports={fn,we};
//main.js
var hi = require('./hellow');
console.log(hi.we);
hi.fn();
加载顺序
exports 和 module.exports 的使用
如果要对外暴露属性或方法,就用 exports 就行,要暴露对象(类似class,包含了很多属性和方法),就用 module.exports。
4、包结构
符合commonJS规范的包目录包含以下的文件
(不一定都有)
- package.json:包描述文件
- bin:用于存放可执行二进制文件的目录
- lib:用于存放JavaScript代码的目录
- doc:用于存放文档的目录
- test:用于存放单元测试用例的代码
生成包描述文件
终端输入:
npm init
5、文件系统
Node.js 文件系统(fs 模块)模块中的方法均有异步和同步版本,例如读取文件内容的函数有异步的 fs.readFile() 和同步的 fs.readFileSync()。
异步的方法函数最后一个参数为回调函数,回调函数的第一个参数包含了错误信息(error),比起同步,异步方法性能更高,速度更快,而且没有阻塞。
文件同步写入
var fs=require('fs');
//同步打开文件
let fd=fs.openSync("input.txt","w");
console.log(fd);
//同步写入文件
let str="hiiiiiii";
fs.writeFileSync(fd,str);
//同步关闭文件
fs.closeSync(fd);
文件异步写入
let fs=require("fs");
fs.open("inpuct.txt","w",(err,fd)=>{
fs.write(fd,"good good study",function(err){
if(!err){
console.log("写入成功");
fs.close(fd,function(){
console.log("关闭成功");
})
}
})
})
console.log("程序执行完成");
不阻塞,继续执行
文件流写入
let fs=require("fs");
//创建写入流
let ws=fs.createWriteStream("input.txt");
//监听流开启
ws.once('open',()=>{
console.log("通道打开");
ws.write("11111111");
ws.write("22222222");
ws.write("33333333");
//写入结束
ws.end();
})
//监听关闭
ws.once('close',()=>{
console.log("通道关闭");
})
console.log("执行完成");
文件读取
let fs=require('fs');
//异步读取文件
fs.readFile("input.txt",(err,data)=>{
if(!err)
{
console.log(data);
}
else{
console.log("error:",err);
}
})
console.log("读取文件完毕");
计算机的存储是以二进制的形式存储的,需要转换成字符串。
let fs=require('fs');
//异步读取文件
fs.readFile("input.txt",(err,data)=>{
if(!err)
{
console.log(data.toString());
}
else{
console.log("error:",err);
}
})
console.log("读取文件完毕");
文件删除
let fs=require('fs');
fs.unlink('inpuct.txt',(err)=>{
if(err)
{
console.log(err);
}
else{
console.log("文件删除成功");
}
})
文件目录读取
let fs=require('fs');
//当前目录下目录异步读取
fs.readdir("./",(err,data)=>{
if(err)
{
console.log(err);
}
else{
console.log(data);
}
})
console.log("文件目录读取完成");
创建文件夹
let fs=require('fs');
//创建文件夹
fs.mkdir('./img',(err)=>{
if(err){
console.log(err);
}
else{
console.log('创建成功');
}
})
删除文件夹
删除空目录
let fs=require('fs');
//删除文件夹
fs.rmdir('./img',(err)=>{
if(err){
console.log(err);
}
else{
console.log('删除成功');
}
})
非空目录
let fs=require('fs');
//递归删除非空目录
function delDir(dirPath){
var filesArr=fs.readdirSync(dirPath);
var filePath=dirPath+'/'+filesArr[i];
//读取文件信息
var stat=fs.statSync(filePath);
//判断文件还是目录
if(stat.isFile()){
//如果是文件就删除
fs.unlinkSync(filePath)
}
else if(stat.isDirectory){
//如果是目录
//递归调用函数
delDir();
}
}
//删除空目录
fs.rmdirSync(dirPath);
6、事件
通过引入 events 模块,并通过实例化 EventEmitter 类来绑定和监听事件
let fs=require('fs');
let events=require('events');
//创建事件对象
var eventLog=new events.EventEmitter();
//监听事件
// 绑定事件及事件的处理程序
eventLog.on('qwer',function(){
console.log("事件触发");
})
//触发事件
eventLog.emit("qwer");
console.log("完成");
带参数触发
let fs=require('fs');
let events=require('events');
//创建事件对象
var eventLog=new events.EventEmitter();
//监听事件
eventLog.on('qwer',function(msg){
console.log(msg+"事件触发");
})
//触发事件
eventLog.emit("qwer","goodgoodstudy");
console.log("完成");
7、Buffer
该类用来创建一个专门存放二进制数据的缓存区。
在v6.0之前创建Buffer对象直接使用new Buffer()构造函数来创建对象实例,但是Buffer对内存的权限操作相比很大,可以直接捕获一些敏感信息,所以在v6.0以后,官方文档里面建议使用 Buffer.from() 接口去创建Buffer对象。
//将10存进缓冲区
let b1=Buffer.from('10');
console.log(b1);
console.log(b1.toString());
//初始化缓冲区,创建一个大小为10个字节的缓冲区
let b2=Buffer.alloc(10);
console.log(b2);
//创建一个大小为10个字节的缓冲区,不会重置数据
let b3=Buffer.allocUnsafe(10);
console.log(b3);
8、多进程
Node.js 是以单线程的模式运行的,但它使用的是事件驱动来处理并发,这样有助于我们在多核 cpu 的系统上创建多个子进程,从而提高性能。
Node 提供了 child_process 模块来创建子进程,方法有:
exec
- child_process.exec 使用子进程执行命令,缓存子进程的输出,并将子进程的输出以回调函数参数的形式返回。spawn
- child_process.spawn`使用指定的命令行参数创建新进程。fork
- child_process.fork 是 spawn()的特殊形式,用于在子进程中运行的模块,如fork(’./son.js’) 相当于 spawn(‘node’, [’./son.js’]) 。与spawn方法不同的是,fork会在父进程与子进程之间,建立一个通信管道,用于进程之间的通信。
exec() 方法
使用子进程执行命令,缓存子进程的输出,并将子进程的输出以回调函数参数的形式返回
//main.js
const fs = require('fs');
const child_process = require('child_process');
for(var i=0; i<3; i++) {
var workerProcess = child_process.exec('node file.js '+i, function (error, stdout, stderr) {
if (error) {
console.log(error.stack);
console.log('Error code: '+error.code);
console.log('Signal received: '+error.signal);
}
console.log('stdout: ' + stdout);
console.log('stderr: ' + stderr);
});
workerProcess.on('exit', function (code) {
console.log('子进程已退出,退出码 '+code);
});
}
//file.js
console.log("进程 " + process.argv[2] + " 执行。" );
spawn() 方法
使用指定的命令行参数创建新进程
//main.js
const fs = require('fs');
const child_process = require('child_process');
for(var i=0; i<3; i++) {
var workerProcess = child_process.spawn('node', ['file.js', i]);
workerProcess.stdout.on('data', function (data) {
console.log('stdout: ' + data);
});
workerProcess.stderr.on('data', function (data) {
console.log('stderr: ' + data);
});
workerProcess.on('close', function (code) {
console.log('子进程已退出,退出码 '+code);
});
}
//file.js
console.log("进程 " + process.argv[2] + " 执行。" );
fork
fork 是 spawn() 方法的特殊形式,用于创建进程
//main.js
const fs = require('fs');
const child_process = require('child_process');
for(var i=0; i<3; i++) {
var worker_process = child_process.fork("file.js", [i]);
worker_process.on('close', function (code) {
console.log('子进程已退出,退出码 ' + code);
});
}
//file.js
console.log("进程 " + process.argv[2] + " 执行。" );
9、Http模块
//引入node的http模块
let http=require('http');
//创建服务器实例
let server=http.createServer();
//服务器监听请求数据
server.on('request',(req,res)=>{
console.log(req.url);
res.end("helloworld");
})
//绑定监听的端口号
server.listen(3000,()=>{
console.log("服务器启动");
})