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对象的属性上
function hello(){
console.log("hello");
}
const we=2;
exports.world=hello;
var hi = require('./hellow');
hi.world();
方法二:
用module.exports对象整体导出一个函数或者变量对象 格式如下:
module.exports = function() {
}
function fn() {
console.log("fn");
}
var we =2;
module.exports={fn,we};
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对象。
let b1=Buffer.from('10');
console.log(b1);
console.log(b1.toString());

let b2=Buffer.alloc(10);
console.log(b2);
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() 方法
使用子进程执行命令,缓存子进程的输出,并将子进程的输出以回调函数参数的形式返回
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);
});
}
console.log("进程 " + process.argv[2] + " 执行。" );
spawn() 方法
使用指定的命令行参数创建新进程
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);
});
}
console.log("进程 " + process.argv[2] + " 执行。" );
fork
fork 是 spawn() 方法的特殊形式,用于创建进程
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);
});
}
console.log("进程 " + process.argv[2] + " 执行。" );
9、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("服务器启动");
})
|